Commit 7a4b15cdf3d607152ba23fa4aa2bf072c6810924

Authored by Benjamin Herrenschmidt
1 parent 81e5d8646f

powerpc/pmac: Convert therm_adt746x to new i2c probing

This simplifies the driver to stop using the deprecated attach interface,

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Showing 1 changed file with 204 additions and 276 deletions Side-by-side Diff

drivers/macintosh/therm_adt746x.c
... ... @@ -47,7 +47,7 @@
47 47  
48 48 static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */
49 49 static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */
50   -static const char *sensor_location[3];
  50 +static const char *sensor_location[3] = { "?", "?", "?" };
51 51  
52 52 static int limit_adjust;
53 53 static int fan_speed = -1;
54 54  
55 55  
... ... @@ -79,18 +79,16 @@
79 79 int last_speed[2];
80 80 int last_var[2];
81 81 int pwm_inv[2];
  82 + struct task_struct *thread;
  83 + struct platform_device *pdev;
  84 + enum {
  85 + ADT7460,
  86 + ADT7467
  87 + } type;
82 88 };
83 89  
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 90 static void write_both_fan_speed(struct thermostat *th, int speed);
91 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 92  
95 93 static int
96 94 write_reg(struct thermostat* th, int reg, u8 data)
... ... @@ -126,66 +124,6 @@
126 124 return data;
127 125 }
128 126  
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 127 static int read_fan_speed(struct thermostat *th, u8 addr)
190 128 {
191 129 u8 tmp[2];
... ... @@ -203,7 +141,7 @@
203 141 static void write_both_fan_speed(struct thermostat *th, int speed)
204 142 {
205 143 write_fan_speed(th, speed, 0);
206   - if (therm_type == ADT7460)
  144 + if (th->type == ADT7460)
207 145 write_fan_speed(th, speed, 1);
208 146 }
209 147  
... ... @@ -216,7 +154,7 @@
216 154 else if (speed < -1)
217 155 speed = 0;
218 156  
219   - if (therm_type == ADT7467 && fan == 1)
  157 + if (th->type == ADT7467 && fan == 1)
220 158 return;
221 159  
222 160 if (th->last_speed[fan] != speed) {
... ... @@ -239,7 +177,7 @@
239 177 write_reg(th, FAN_SPD_SET[fan], speed);
240 178 } else {
241 179 /* back to automatic */
242   - if(therm_type == ADT7460) {
  180 + if(th->type == ADT7460) {
243 181 manual = read_reg(th,
244 182 MANUAL_MODE[fan]) & (~MANUAL_MASK);
245 183 manual &= ~INVERT_MASK;
... ... @@ -293,7 +231,7 @@
293 231 /* we don't care about local sensor, so we start at sensor 1 */
294 232 for (i = 1; i < 3; i++) {
295 233 int started = 0;
296   - int fan_number = (therm_type == ADT7460 && i == 2);
  234 + int fan_number = (th->type == ADT7460 && i == 2);
297 235 int var = th->temps[i] - th->limits[i];
298 236  
299 237 if (var > -1) {
300 238  
301 239  
302 240  
... ... @@ -370,116 +308,22 @@
370 308  
371 309 static void set_limit(struct thermostat *th, int i)
372 310 {
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]);
  311 + /* Set sensor1 limit higher to avoid powerdowns */
  312 + th->limits[i] = default_limits_chip[i] + limit_adjust;
  313 + write_reg(th, LIMIT_REG[i], th->limits[i]);
376 314  
377   - /* set our limits to normal */
378   - th->limits[i] = default_limits_local[i] + limit_adjust;
  315 + /* set our limits to normal */
  316 + th->limits[i] = default_limits_local[i] + limit_adjust;
379 317 }
380 318  
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;
  319 +#define BUILD_SHOW_FUNC_INT(name, data) \
  320 +static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
  321 +{ \
  322 + struct thermostat *th = dev_get_drvdata(dev); \
  323 + return sprintf(buf, "%d\n", data); \
458 324 }
459 325  
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) \
  326 +#define BUILD_SHOW_FUNC_INT_LITE(name, data) \
483 327 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
484 328 { \
485 329 return sprintf(buf, "%d\n", data); \
486 330  
487 331  
488 332  
... ... @@ -494,22 +338,24 @@
494 338 #define BUILD_SHOW_FUNC_FAN(name, data) \
495 339 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
496 340 { \
  341 + struct thermostat *th = dev_get_drvdata(dev); \
497 342 return sprintf(buf, "%d (%d rpm)\n", \
498   - thermostat->last_speed[data], \
499   - read_fan_speed(thermostat, FAN_SPEED[data]) \
  343 + th->last_speed[data], \
  344 + read_fan_speed(th, FAN_SPEED[data]) \
500 345 ); \
501 346 }
502 347  
503 348 #define BUILD_STORE_FUNC_DEG(name, data) \
504 349 static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
505 350 { \
  351 + struct thermostat *th = dev_get_drvdata(dev); \
506 352 int val; \
507 353 int i; \
508 354 val = simple_strtol(buf, NULL, 10); \
509 355 printk(KERN_INFO "Adjusting limits by %d degrees\n", val); \
510 356 limit_adjust = val; \
511 357 for (i=0; i < 3; i++) \
512   - set_limit(thermostat, i); \
  358 + set_limit(th, i); \
513 359 return n; \
514 360 }
515 361  
516 362  
517 363  
... ... @@ -525,20 +371,21 @@
525 371 return n; \
526 372 }
527 373  
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])
  374 +BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(th, TEMP_REG[1])))
  375 +BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(th, TEMP_REG[2])))
  376 +BUILD_SHOW_FUNC_INT(sensor1_limit, th->limits[1])
  377 +BUILD_SHOW_FUNC_INT(sensor2_limit, th->limits[2])
532 378 BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1])
533 379 BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2])
534 380  
535   -BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed)
  381 +BUILD_SHOW_FUNC_INT_LITE(specified_fan_speed, fan_speed)
  382 +BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed)
  383 +
536 384 BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0)
537 385 BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1)
538 386  
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)
  387 +BUILD_SHOW_FUNC_INT_LITE(limit_adjust, limit_adjust)
  388 +BUILD_STORE_FUNC_DEG(limit_adjust, th)
542 389  
543 390 static DEVICE_ATTR(sensor1_temperature, S_IRUGO,
544 391 show_sensor1_temperature,NULL);
545 392  
546 393  
547 394  
548 395  
549 396  
550 397  
551 398  
... ... @@ -564,53 +411,77 @@
564 411 static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
565 412 show_limit_adjust, store_limit_adjust);
566 413  
567   -
568   -static int __init
569   -thermostat_init(void)
  414 +static void thermostat_create_files(struct thermostat *th)
570 415 {
571   - struct device_node* np;
572   - const u32 *prop;
573   - int i = 0, offset = 0;
  416 + struct device_node *np = th->clt->dev.of_node;
  417 + struct device *dev;
  418 + int err;
574 419  
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   - }
  420 + /* To maintain ABI compatibility with userspace, create
  421 + * the old style platform driver and attach the attributes
  422 + * to it here
  423 + */
  424 + th->pdev = of_platform_device_create(np, "temperatures", NULL);
  425 + if (!th->pdev)
  426 + return;
  427 + dev = &th->pdev->dev;
  428 + dev_set_drvdata(dev, th);
  429 + err = device_create_file(dev, &dev_attr_sensor1_temperature);
  430 + err |= device_create_file(dev, &dev_attr_sensor2_temperature);
  431 + err |= device_create_file(dev, &dev_attr_sensor1_limit);
  432 + err |= device_create_file(dev, &dev_attr_sensor2_limit);
  433 + err |= device_create_file(dev, &dev_attr_sensor1_location);
  434 + err |= device_create_file(dev, &dev_attr_sensor2_location);
  435 + err |= device_create_file(dev, &dev_attr_limit_adjust);
  436 + err |= device_create_file(dev, &dev_attr_specified_fan_speed);
  437 + err |= device_create_file(dev, &dev_attr_sensor1_fan_speed);
  438 + if(th->type == ADT7460)
  439 + err |= device_create_file(dev, &dev_attr_sensor2_fan_speed);
  440 + if (err)
  441 + printk(KERN_WARNING
  442 + "Failed to create temperature attribute file(s).\n");
  443 +}
586 444  
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   - }
  445 +static void thermostat_remove_files(struct thermostat *th)
  446 +{
  447 + struct device *dev;
594 448  
595   - prop = of_get_property(np, "reg", NULL);
596   - if (!prop) {
597   - of_node_put(np);
598   - return -ENODEV;
599   - }
  449 + if (!th->pdev)
  450 + return;
  451 + dev = &th->pdev->dev;
  452 + device_remove_file(dev, &dev_attr_sensor1_temperature);
  453 + device_remove_file(dev, &dev_attr_sensor2_temperature);
  454 + device_remove_file(dev, &dev_attr_sensor1_limit);
  455 + device_remove_file(dev, &dev_attr_sensor2_limit);
  456 + device_remove_file(dev, &dev_attr_sensor1_location);
  457 + device_remove_file(dev, &dev_attr_sensor2_location);
  458 + device_remove_file(dev, &dev_attr_limit_adjust);
  459 + device_remove_file(dev, &dev_attr_specified_fan_speed);
  460 + device_remove_file(dev, &dev_attr_sensor1_fan_speed);
  461 + if (th->type == ADT7460)
  462 + device_remove_file(dev, &dev_attr_sensor2_fan_speed);
  463 + of_device_unregister(th->pdev);
600 464  
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   - }
  465 +}
608 466  
609   - therm_address = ((*prop) & 0xff) >> 1;
  467 +static int probe_thermostat(struct i2c_client *client,
  468 + const struct i2c_device_id *id)
  469 +{
  470 + struct device_node *np = client->dev.of_node;
  471 + struct thermostat* th;
  472 + const __be32 *prop;
  473 + int i, rc, vers, offset = 0;
610 474  
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);
  475 + if (!np)
  476 + return -ENXIO;
  477 + prop = of_get_property(np, "hwsensor-params-version", NULL);
  478 + if (!prop)
  479 + return -ENXIO;
  480 + vers = be32_to_cpup(prop);
  481 + printk(KERN_INFO "adt746x: version %d (%ssupported)\n",
  482 + vers, vers == 1 ? "" : "un");
  483 + if (vers != 1)
  484 + return -ENXIO;
614 485  
615 486 if (of_get_property(np, "hwsensor-location", NULL)) {
616 487 for (i = 0; i < 3; i++) {
617 488  
618 489  
619 490  
620 491  
621 492  
622 493  
623 494  
624 495  
625 496  
626 497  
627 498  
628 499  
... ... @@ -623,72 +494,129 @@
623 494 printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]);
624 495 offset += strlen(sensor_location[i]) + 1;
625 496 }
626   - } else {
627   - sensor_location[0] = "?";
628   - sensor_location[1] = "?";
629   - sensor_location[2] = "?";
630 497 }
631 498  
632   - of_dev = of_platform_device_create(np, "temperatures", NULL);
633   - of_node_put(np);
  499 + th = kzalloc(sizeof(struct thermostat), GFP_KERNEL);
  500 + if (!th)
  501 + return -ENOMEM;
634 502  
635   - if (of_dev == NULL) {
636   - printk(KERN_ERR "Can't register temperatures device !\n");
  503 + i2c_set_clientdata(client, th);
  504 + th->clt = client;
  505 + th->type = id->driver_data;
  506 +
  507 + rc = read_reg(th, CONFIG_REG);
  508 + if (rc < 0) {
  509 + dev_err(&client->dev, "Thermostat failed to read config!\n");
  510 + kfree(th);
637 511 return -ENODEV;
638 512 }
639 513  
640   -#ifndef CONFIG_I2C_POWERMAC
641   - request_module("i2c-powermac");
642   -#endif
  514 + /* force manual control to start the fan quieter */
  515 + if (fan_speed == -1)
  516 + fan_speed = 64;
  517 +
  518 + if (th->type == ADT7460) {
  519 + printk(KERN_INFO "adt746x: ADT7460 initializing\n");
  520 + /* The 7460 needs to be started explicitly */
  521 + write_reg(th, CONFIG_REG, 1);
  522 + } else
  523 + printk(KERN_INFO "adt746x: ADT7467 initializing\n");
643 524  
644   - return i2c_add_driver(&thermostat_driver);
  525 + for (i = 0; i < 3; i++) {
  526 + th->initial_limits[i] = read_reg(th, LIMIT_REG[i]);
  527 + set_limit(th, i);
  528 + }
  529 +
  530 + printk(KERN_INFO "adt746x: Lowering max temperatures from %d, %d, %d"
  531 + " to %d, %d, %d\n",
  532 + th->initial_limits[0], th->initial_limits[1],
  533 + th->initial_limits[2], th->limits[0], th->limits[1],
  534 + th->limits[2]);
  535 +
  536 + /* record invert bit status because fw can corrupt it after suspend */
  537 + th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK;
  538 + th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK;
  539 +
  540 + /* be sure to really write fan speed the first time */
  541 + th->last_speed[0] = -2;
  542 + th->last_speed[1] = -2;
  543 + th->last_var[0] = -80;
  544 + th->last_var[1] = -80;
  545 +
  546 + if (fan_speed != -1) {
  547 + /* manual mode, stop fans */
  548 + write_both_fan_speed(th, 0);
  549 + } else {
  550 + /* automatic mode */
  551 + write_both_fan_speed(th, -1);
  552 + }
  553 +
  554 + th->thread = kthread_run(monitor_task, th, "kfand");
  555 + if (th->thread == ERR_PTR(-ENOMEM)) {
  556 + printk(KERN_INFO "adt746x: Kthread creation failed\n");
  557 + th->thread = NULL;
  558 + return -ENOMEM;
  559 + }
  560 +
  561 + thermostat_create_files(th);
  562 +
  563 + return 0;
645 564 }
646 565  
647   -static void thermostat_create_files(void)
  566 +static int remove_thermostat(struct i2c_client *client)
648 567 {
649   - int err;
  568 + struct thermostat *th = i2c_get_clientdata(client);
  569 + int i;
  570 +
  571 + thermostat_remove_files(th);
650 572  
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");
  573 + if (th->thread != NULL)
  574 + kthread_stop(th->thread);
  575 +
  576 + printk(KERN_INFO "adt746x: Putting max temperatures back from "
  577 + "%d, %d, %d to %d, %d, %d\n",
  578 + th->limits[0], th->limits[1], th->limits[2],
  579 + th->initial_limits[0], th->initial_limits[1],
  580 + th->initial_limits[2]);
  581 +
  582 + for (i = 0; i < 3; i++)
  583 + write_reg(th, LIMIT_REG[i], th->initial_limits[i]);
  584 +
  585 + write_both_fan_speed(th, -1);
  586 +
  587 + kfree(th);
  588 +
  589 + return 0;
665 590 }
666 591  
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);
  592 +static const struct i2c_device_id therm_adt746x_id[] = {
  593 + { "MAC,adt7460", ADT7460 },
  594 + { "MAC,adt7467", ADT7467 },
  595 + { }
  596 +};
  597 +MODULE_DEVICE_TABLE(i2c, therm_adt746x_id);
679 598  
680   - if(therm_type == ADT7460)
681   - device_remove_file(&of_dev->dev,
682   - &dev_attr_sensor2_fan_speed);
  599 +static struct i2c_driver thermostat_driver = {
  600 + .driver = {
  601 + .name = "therm_adt746x",
  602 + },
  603 + .probe = probe_thermostat,
  604 + .remove = remove_thermostat,
  605 + .id_table = therm_adt746x_id,
  606 +};
683 607  
684   - }
  608 +static int __init thermostat_init(void)
  609 +{
  610 +#ifndef CONFIG_I2C_POWERMAC
  611 + request_module("i2c-powermac");
  612 +#endif
  613 +
  614 + return i2c_add_driver(&thermostat_driver);
685 615 }
686 616  
687   -static void __exit
688   -thermostat_exit(void)
  617 +static void __exit thermostat_exit(void)
689 618 {
690 619 i2c_del_driver(&thermostat_driver);
691   - of_device_unregister(of_dev);
692 620 }
693 621  
694 622 module_init(thermostat_init);