aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/smsc47m1.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-05-08 11:22:00 -0400
committerJean Delvare <khali@hyperion.delvare>2007-05-08 11:22:00 -0400
commit51f2cca1f72db5e272ed79b678b62fb9472e916e (patch)
tree97f3786d3a143539c68bd81cd6d8545e83c38987 /drivers/hwmon/smsc47m1.c
parent2dbc514a2ed2b6f71eb6d18671d2c663160788c9 (diff)
hwmon/smsc47m1: Convert to a platform driver
Convert the smsc47m1 driver from the nonsensical i2c-isa hack to a regular platform driver. Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/smsc47m1.c')
-rw-r--r--drivers/hwmon/smsc47m1.c327
1 files changed, 193 insertions, 134 deletions
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index f219d7c6a982..223708897e8e 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -30,8 +30,7 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/jiffies.h> 32#include <linux/jiffies.h>
33#include <linux/i2c.h> 33#include <linux/platform_device.h>
34#include <linux/i2c-isa.h>
35#include <linux/hwmon.h> 34#include <linux/hwmon.h>
36#include <linux/err.h> 35#include <linux/err.h>
37#include <linux/init.h> 36#include <linux/init.h>
@@ -39,9 +38,9 @@
39#include <linux/sysfs.h> 38#include <linux/sysfs.h>
40#include <asm/io.h> 39#include <asm/io.h>
41 40
42/* Address is autodetected, there is no default value */ 41static struct platform_device *pdev;
43static unsigned short address; 42
44static u8 devid; 43#define DRVNAME "smsc47m1"
45enum chips { smsc47m1, smsc47m2 }; 44enum chips { smsc47m1, smsc47m2 };
46 45
47/* Super-I/0 registers and commands */ 46/* Super-I/0 registers and commands */
@@ -113,7 +112,8 @@ static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 };
113#define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E) 112#define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E)
114 113
115struct smsc47m1_data { 114struct smsc47m1_data {
116 struct i2c_client client; 115 unsigned short addr;
116 const char *name;
117 enum chips type; 117 enum chips type;
118 struct class_device *class_dev; 118 struct class_device *class_dev;
119 119
@@ -127,30 +127,34 @@ struct smsc47m1_data {
127 u8 pwm[3]; /* Register value (bit 0 is disable) */ 127 u8 pwm[3]; /* Register value (bit 0 is disable) */
128}; 128};
129 129
130struct smsc47m1_sio_data {
131 enum chips type;
132};
130 133
131static int smsc47m1_detect(struct i2c_adapter *adapter); 134
132static int smsc47m1_detach_client(struct i2c_client *client); 135static int smsc47m1_probe(struct platform_device *pdev);
136static int smsc47m1_remove(struct platform_device *pdev);
133static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 137static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
134 int init); 138 int init);
135 139
136static inline int smsc47m1_read_value(struct i2c_client *client, u8 reg) 140static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg)
137{ 141{
138 return inb_p(client->addr + reg); 142 return inb_p(data->addr + reg);
139} 143}
140 144
141static inline void smsc47m1_write_value(struct i2c_client *client, u8 reg, 145static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg,
142 u8 value) 146 u8 value)
143{ 147{
144 outb_p(value, client->addr + reg); 148 outb_p(value, data->addr + reg);
145} 149}
146 150
147static struct i2c_driver smsc47m1_driver = { 151static struct platform_driver smsc47m1_driver = {
148 .driver = { 152 .driver = {
149 .owner = THIS_MODULE, 153 .owner = THIS_MODULE,
150 .name = "smsc47m1", 154 .name = DRVNAME,
151 }, 155 },
152 .attach_adapter = smsc47m1_detect, 156 .probe = smsc47m1_probe,
153 .detach_client = smsc47m1_detach_client, 157 .remove = __devexit_p(smsc47m1_remove),
154}; 158};
155 159
156/* nr is 0 or 1 in the callback functions below */ 160/* nr is 0 or 1 in the callback functions below */
@@ -204,8 +208,7 @@ static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, cha
204static ssize_t set_fan_min(struct device *dev, const char *buf, 208static ssize_t set_fan_min(struct device *dev, const char *buf,
205 size_t count, int nr) 209 size_t count, int nr)
206{ 210{
207 struct i2c_client *client = to_i2c_client(dev); 211 struct smsc47m1_data *data = dev_get_drvdata(dev);
208 struct smsc47m1_data *data = i2c_get_clientdata(client);
209 long rpmdiv, val = simple_strtol(buf, NULL, 10); 212 long rpmdiv, val = simple_strtol(buf, NULL, 10);
210 213
211 mutex_lock(&data->update_lock); 214 mutex_lock(&data->update_lock);
@@ -217,7 +220,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
217 } 220 }
218 221
219 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv); 222 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
220 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD[nr], 223 smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
221 data->fan_preload[nr]); 224 data->fan_preload[nr]);
222 mutex_unlock(&data->update_lock); 225 mutex_unlock(&data->update_lock);
223 226
@@ -231,8 +234,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
231static ssize_t set_fan_div(struct device *dev, const char *buf, 234static ssize_t set_fan_div(struct device *dev, const char *buf,
232 size_t count, int nr) 235 size_t count, int nr)
233{ 236{
234 struct i2c_client *client = to_i2c_client(dev); 237 struct smsc47m1_data *data = dev_get_drvdata(dev);
235 struct smsc47m1_data *data = i2c_get_clientdata(client);
236 238
237 long new_div = simple_strtol(buf, NULL, 10), tmp; 239 long new_div = simple_strtol(buf, NULL, 10), tmp;
238 u8 old_div = DIV_FROM_REG(data->fan_div[nr]); 240 u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
@@ -254,15 +256,15 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
254 switch (nr) { 256 switch (nr) {
255 case 0: 257 case 0:
256 case 1: 258 case 1:
257 tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) 259 tmp = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV)
258 & ~(0x03 << (4 + 2 * nr)); 260 & ~(0x03 << (4 + 2 * nr));
259 tmp |= data->fan_div[nr] << (4 + 2 * nr); 261 tmp |= data->fan_div[nr] << (4 + 2 * nr);
260 smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp); 262 smsc47m1_write_value(data, SMSC47M1_REG_FANDIV, tmp);
261 break; 263 break;
262 case 2: 264 case 2:
263 tmp = smsc47m1_read_value(client, SMSC47M2_REG_FANDIV3) & 0xCF; 265 tmp = smsc47m1_read_value(data, SMSC47M2_REG_FANDIV3) & 0xCF;
264 tmp |= data->fan_div[2] << 4; 266 tmp |= data->fan_div[2] << 4;
265 smsc47m1_write_value(client, SMSC47M2_REG_FANDIV3, tmp); 267 smsc47m1_write_value(data, SMSC47M2_REG_FANDIV3, tmp);
266 break; 268 break;
267 } 269 }
268 270
@@ -270,7 +272,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
270 tmp = 192 - (old_div * (192 - data->fan_preload[nr]) 272 tmp = 192 - (old_div * (192 - data->fan_preload[nr])
271 + new_div / 2) / new_div; 273 + new_div / 2) / new_div;
272 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191); 274 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
273 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD[nr], 275 smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
274 data->fan_preload[nr]); 276 data->fan_preload[nr]);
275 mutex_unlock(&data->update_lock); 277 mutex_unlock(&data->update_lock);
276 278
@@ -280,8 +282,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
280static ssize_t set_pwm(struct device *dev, const char *buf, 282static ssize_t set_pwm(struct device *dev, const char *buf,
281 size_t count, int nr) 283 size_t count, int nr)
282{ 284{
283 struct i2c_client *client = to_i2c_client(dev); 285 struct smsc47m1_data *data = dev_get_drvdata(dev);
284 struct smsc47m1_data *data = i2c_get_clientdata(client);
285 286
286 long val = simple_strtol(buf, NULL, 10); 287 long val = simple_strtol(buf, NULL, 10);
287 288
@@ -291,7 +292,7 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
291 mutex_lock(&data->update_lock); 292 mutex_lock(&data->update_lock);
292 data->pwm[nr] &= 0x81; /* Preserve additional bits */ 293 data->pwm[nr] &= 0x81; /* Preserve additional bits */
293 data->pwm[nr] |= PWM_TO_REG(val); 294 data->pwm[nr] |= PWM_TO_REG(val);
294 smsc47m1_write_value(client, SMSC47M1_REG_PWM[nr], 295 smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
295 data->pwm[nr]); 296 data->pwm[nr]);
296 mutex_unlock(&data->update_lock); 297 mutex_unlock(&data->update_lock);
297 298
@@ -301,8 +302,7 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
301static ssize_t set_pwm_en(struct device *dev, const char *buf, 302static ssize_t set_pwm_en(struct device *dev, const char *buf,
302 size_t count, int nr) 303 size_t count, int nr)
303{ 304{
304 struct i2c_client *client = to_i2c_client(dev); 305 struct smsc47m1_data *data = dev_get_drvdata(dev);
305 struct smsc47m1_data *data = i2c_get_clientdata(client);
306 306
307 long val = simple_strtol(buf, NULL, 10); 307 long val = simple_strtol(buf, NULL, 10);
308 308
@@ -312,7 +312,7 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
312 mutex_lock(&data->update_lock); 312 mutex_lock(&data->update_lock);
313 data->pwm[nr] &= 0xFE; /* preserve the other bits */ 313 data->pwm[nr] &= 0xFE; /* preserve the other bits */
314 data->pwm[nr] |= !val; 314 data->pwm[nr] |= !val;
315 smsc47m1_write_value(client, SMSC47M1_REG_PWM[nr], 315 smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
316 data->pwm[nr]); 316 data->pwm[nr]);
317 mutex_unlock(&data->update_lock); 317 mutex_unlock(&data->update_lock);
318 318
@@ -377,6 +377,15 @@ fan_present(3);
377 377
378static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); 378static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
379 379
380static ssize_t show_name(struct device *dev, struct device_attribute
381 *devattr, char *buf)
382{
383 struct smsc47m1_data *data = dev_get_drvdata(dev);
384
385 return sprintf(buf, "%s\n", data->name);
386}
387static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
388
380/* Almost all sysfs files may or may not be created depending on the chip 389/* Almost all sysfs files may or may not be created depending on the chip
381 setup so we create them individually. It is still convenient to define a 390 setup so we create them individually. It is still convenient to define a
382 group to remove them all at once. */ 391 group to remove them all at once. */
@@ -399,6 +408,7 @@ static struct attribute *smsc47m1_attributes[] = {
399 &dev_attr_pwm3_enable.attr, 408 &dev_attr_pwm3_enable.attr,
400 409
401 &dev_attr_alarms.attr, 410 &dev_attr_alarms.attr,
411 &dev_attr_name.attr,
402 NULL 412 NULL
403}; 413};
404 414
@@ -406,12 +416,13 @@ static const struct attribute_group smsc47m1_group = {
406 .attrs = smsc47m1_attributes, 416 .attrs = smsc47m1_attributes,
407}; 417};
408 418
409static int __init smsc47m1_find(unsigned short *addr) 419static int __init smsc47m1_find(unsigned short *addr,
420 struct smsc47m1_sio_data *sio_data)
410{ 421{
411 u8 val; 422 u8 val;
412 423
413 superio_enter(); 424 superio_enter();
414 devid = superio_inb(SUPERIO_REG_DEVID); 425 val = superio_inb(SUPERIO_REG_DEVID);
415 426
416 /* 427 /*
417 * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x 428 * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x
@@ -424,23 +435,28 @@ static int __init smsc47m1_find(unsigned short *addr)
424 * supports a 3rd fan, and the pin configuration registers are 435 * supports a 3rd fan, and the pin configuration registers are
425 * unfortunately different. 436 * unfortunately different.
426 */ 437 */
427 switch (devid) { 438 switch (val) {
428 case 0x51: 439 case 0x51:
429 printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n"); 440 printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
441 sio_data->type = smsc47m1;
430 break; 442 break;
431 case 0x59: 443 case 0x59:
432 printk(KERN_INFO "smsc47m1: Found SMSC " 444 printk(KERN_INFO "smsc47m1: Found SMSC "
433 "LPC47M10x/LPC47M112/LPC47M13x\n"); 445 "LPC47M10x/LPC47M112/LPC47M13x\n");
446 sio_data->type = smsc47m1;
434 break; 447 break;
435 case 0x5F: 448 case 0x5F:
436 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n"); 449 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
450 sio_data->type = smsc47m1;
437 break; 451 break;
438 case 0x60: 452 case 0x60:
439 printk(KERN_INFO "smsc47m1: Found SMSC " 453 printk(KERN_INFO "smsc47m1: Found SMSC "
440 "LPC47M15x/LPC47M192/LPC47M997\n"); 454 "LPC47M15x/LPC47M192/LPC47M997\n");
455 sio_data->type = smsc47m1;
441 break; 456 break;
442 case 0x6B: 457 case 0x6B:
443 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M292\n"); 458 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M292\n");
459 sio_data->type = smsc47m2;
444 break; 460 break;
445 default: 461 default:
446 superio_exit(); 462 superio_exit();
@@ -461,15 +477,25 @@ static int __init smsc47m1_find(unsigned short *addr)
461 return 0; 477 return 0;
462} 478}
463 479
464static int smsc47m1_detect(struct i2c_adapter *adapter) 480static int __devinit smsc47m1_probe(struct platform_device *pdev)
465{ 481{
466 struct i2c_client *new_client; 482 struct device *dev = &pdev->dev;
483 struct smsc47m1_sio_data *sio_data = dev->platform_data;
467 struct smsc47m1_data *data; 484 struct smsc47m1_data *data;
485 struct resource *res;
468 int err = 0; 486 int err = 0;
469 int fan1, fan2, fan3, pwm1, pwm2, pwm3; 487 int fan1, fan2, fan3, pwm1, pwm2, pwm3;
470 488
471 if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) { 489 static const char *names[] = {
472 dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); 490 "smsc47m1",
491 "smsc47m2",
492 };
493
494 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
495 if (!request_region(res->start, SMSC_EXTENT, DRVNAME)) {
496 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
497 (unsigned long)res->start,
498 (unsigned long)res->end);
473 return -EBUSY; 499 return -EBUSY;
474 } 500 }
475 501
@@ -478,131 +504,99 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
478 goto error_release; 504 goto error_release;
479 } 505 }
480 506
481 data->type = devid == 0x6B ? smsc47m2 : smsc47m1; 507 data->addr = res->start;
482 new_client = &data->client; 508 data->type = sio_data->type;
483 i2c_set_clientdata(new_client, data); 509 data->name = names[sio_data->type];
484 new_client->addr = address;
485 new_client->adapter = adapter;
486 new_client->driver = &smsc47m1_driver;
487 new_client->flags = 0;
488
489 strlcpy(new_client->name,
490 data->type == smsc47m2 ? "smsc47m2" : "smsc47m1",
491 I2C_NAME_SIZE);
492 mutex_init(&data->update_lock); 510 mutex_init(&data->update_lock);
511 platform_set_drvdata(pdev, data);
493 512
494 /* If no function is properly configured, there's no point in 513 /* If no function is properly configured, there's no point in
495 actually registering the chip. */ 514 actually registering the chip. */
496 pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05) 515 pwm1 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(0)) & 0x05)
497 == 0x04; 516 == 0x04;
498 pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05) 517 pwm2 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(1)) & 0x05)
499 == 0x04; 518 == 0x04;
500 if (data->type == smsc47m2) { 519 if (data->type == smsc47m2) {
501 fan1 = (smsc47m1_read_value(new_client, SMSC47M2_REG_TPIN1) 520 fan1 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN1)
502 & 0x0d) == 0x09; 521 & 0x0d) == 0x09;
503 fan2 = (smsc47m1_read_value(new_client, SMSC47M2_REG_TPIN2) 522 fan2 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN2)
504 & 0x0d) == 0x09; 523 & 0x0d) == 0x09;
505 fan3 = (smsc47m1_read_value(new_client, SMSC47M2_REG_TPIN3) 524 fan3 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN3)
506 & 0x0d) == 0x0d; 525 & 0x0d) == 0x0d;
507 pwm3 = (smsc47m1_read_value(new_client, SMSC47M2_REG_PPIN3) 526 pwm3 = (smsc47m1_read_value(data, SMSC47M2_REG_PPIN3)
508 & 0x0d) == 0x08; 527 & 0x0d) == 0x08;
509 } else { 528 } else {
510 fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) 529 fan1 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(0))
511 & 0x05) == 0x05; 530 & 0x05) == 0x05;
512 fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) 531 fan2 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(1))
513 & 0x05) == 0x05; 532 & 0x05) == 0x05;
514 fan3 = 0; 533 fan3 = 0;
515 pwm3 = 0; 534 pwm3 = 0;
516 } 535 }
517 if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) { 536 if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) {
518 dev_warn(&adapter->dev, "Device at 0x%x is not configured, " 537 dev_warn(dev, "Device not configured, will not use\n");
519 "will not use\n", new_client->addr);
520 err = -ENODEV; 538 err = -ENODEV;
521 goto error_free; 539 goto error_free;
522 } 540 }
523 541
524 if ((err = i2c_attach_client(new_client)))
525 goto error_free;
526
527 /* Some values (fan min, clock dividers, pwm registers) may be 542 /* Some values (fan min, clock dividers, pwm registers) may be
528 needed before any update is triggered, so we better read them 543 needed before any update is triggered, so we better read them
529 at least once here. We don't usually do it that way, but in 544 at least once here. We don't usually do it that way, but in
530 this particular case, manually reading 5 registers out of 8 545 this particular case, manually reading 5 registers out of 8
531 doesn't make much sense and we're better using the existing 546 doesn't make much sense and we're better using the existing
532 function. */ 547 function. */
533 smsc47m1_update_device(&new_client->dev, 1); 548 smsc47m1_update_device(dev, 1);
534 549
535 /* Register sysfs hooks */ 550 /* Register sysfs hooks */
536 if (fan1) { 551 if (fan1) {
537 if ((err = device_create_file(&new_client->dev, 552 if ((err = device_create_file(dev, &dev_attr_fan1_input))
538 &dev_attr_fan1_input)) 553 || (err = device_create_file(dev, &dev_attr_fan1_min))
539 || (err = device_create_file(&new_client->dev, 554 || (err = device_create_file(dev, &dev_attr_fan1_div)))
540 &dev_attr_fan1_min))
541 || (err = device_create_file(&new_client->dev,
542 &dev_attr_fan1_div)))
543 goto error_remove_files; 555 goto error_remove_files;
544 } else 556 } else
545 dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, " 557 dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n");
546 "skipping\n");
547 558
548 if (fan2) { 559 if (fan2) {
549 if ((err = device_create_file(&new_client->dev, 560 if ((err = device_create_file(dev, &dev_attr_fan2_input))
550 &dev_attr_fan2_input)) 561 || (err = device_create_file(dev, &dev_attr_fan2_min))
551 || (err = device_create_file(&new_client->dev, 562 || (err = device_create_file(dev, &dev_attr_fan2_div)))
552 &dev_attr_fan2_min))
553 || (err = device_create_file(&new_client->dev,
554 &dev_attr_fan2_div)))
555 goto error_remove_files; 563 goto error_remove_files;
556 } else 564 } else
557 dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, " 565 dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n");
558 "skipping\n");
559 566
560 if (fan3) { 567 if (fan3) {
561 if ((err = device_create_file(&new_client->dev, 568 if ((err = device_create_file(dev, &dev_attr_fan3_input))
562 &dev_attr_fan3_input)) 569 || (err = device_create_file(dev, &dev_attr_fan3_min))
563 || (err = device_create_file(&new_client->dev, 570 || (err = device_create_file(dev, &dev_attr_fan3_div)))
564 &dev_attr_fan3_min))
565 || (err = device_create_file(&new_client->dev,
566 &dev_attr_fan3_div)))
567 goto error_remove_files; 571 goto error_remove_files;
568 } else 572 } else
569 dev_dbg(&new_client->dev, "Fan 3 not enabled by hardware, " 573 dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n");
570 "skipping\n");
571 574
572 if (pwm1) { 575 if (pwm1) {
573 if ((err = device_create_file(&new_client->dev, 576 if ((err = device_create_file(dev, &dev_attr_pwm1))
574 &dev_attr_pwm1)) 577 || (err = device_create_file(dev, &dev_attr_pwm1_enable)))
575 || (err = device_create_file(&new_client->dev,
576 &dev_attr_pwm1_enable)))
577 goto error_remove_files; 578 goto error_remove_files;
578 } else 579 } else
579 dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, " 580 dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n");
580 "skipping\n");
581 581
582 if (pwm2) { 582 if (pwm2) {
583 if ((err = device_create_file(&new_client->dev, 583 if ((err = device_create_file(dev, &dev_attr_pwm2))
584 &dev_attr_pwm2)) 584 || (err = device_create_file(dev, &dev_attr_pwm2_enable)))
585 || (err = device_create_file(&new_client->dev,
586 &dev_attr_pwm2_enable)))
587 goto error_remove_files; 585 goto error_remove_files;
588 } else 586 } else
589 dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, " 587 dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n");
590 "skipping\n");
591 588
592 if (pwm3) { 589 if (pwm3) {
593 if ((err = device_create_file(&new_client->dev, 590 if ((err = device_create_file(dev, &dev_attr_pwm3))
594 &dev_attr_pwm3)) 591 || (err = device_create_file(dev, &dev_attr_pwm3_enable)))
595 || (err = device_create_file(&new_client->dev,
596 &dev_attr_pwm3_enable)))
597 goto error_remove_files; 592 goto error_remove_files;
598 } else 593 } else
599 dev_dbg(&new_client->dev, "PWM 3 not enabled by hardware, " 594 dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n");
600 "skipping\n");
601 595
602 if ((err = device_create_file(&new_client->dev, &dev_attr_alarms))) 596 if ((err = device_create_file(dev, &dev_attr_alarms)))
603 goto error_remove_files; 597 goto error_remove_files;
604 598
605 data->class_dev = hwmon_device_register(&new_client->dev); 599 data->class_dev = hwmon_device_register(dev);
606 if (IS_ERR(data->class_dev)) { 600 if (IS_ERR(data->class_dev)) {
607 err = PTR_ERR(data->class_dev); 601 err = PTR_ERR(data->class_dev);
608 goto error_remove_files; 602 goto error_remove_files;
@@ -611,27 +605,25 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
611 return 0; 605 return 0;
612 606
613error_remove_files: 607error_remove_files:
614 sysfs_remove_group(&new_client->dev.kobj, &smsc47m1_group); 608 sysfs_remove_group(&dev->kobj, &smsc47m1_group);
615 i2c_detach_client(new_client);
616error_free: 609error_free:
617 kfree(data); 610 kfree(data);
618error_release: 611error_release:
619 release_region(address, SMSC_EXTENT); 612 release_region(res->start, SMSC_EXTENT);
620 return err; 613 return err;
621} 614}
622 615
623static int smsc47m1_detach_client(struct i2c_client *client) 616static int __devexit smsc47m1_remove(struct platform_device *pdev)
624{ 617{
625 struct smsc47m1_data *data = i2c_get_clientdata(client); 618 struct smsc47m1_data *data = platform_get_drvdata(pdev);
626 int err; 619 struct resource *res;
627 620
621 platform_set_drvdata(pdev, NULL);
628 hwmon_device_unregister(data->class_dev); 622 hwmon_device_unregister(data->class_dev);
629 sysfs_remove_group(&client->dev.kobj, &smsc47m1_group); 623 sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
630
631 if ((err = i2c_detach_client(client)))
632 return err;
633 624
634 release_region(client->addr, SMSC_EXTENT); 625 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
626 release_region(res->start, SMSC_EXTENT);
635 kfree(data); 627 kfree(data);
636 628
637 return 0; 629 return 0;
@@ -640,8 +632,7 @@ static int smsc47m1_detach_client(struct i2c_client *client)
640static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 632static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
641 int init) 633 int init)
642{ 634{
643 struct i2c_client *client = to_i2c_client(dev); 635 struct smsc47m1_data *data = dev_get_drvdata(dev);
644 struct smsc47m1_data *data = i2c_get_clientdata(client);
645 636
646 mutex_lock(&data->update_lock); 637 mutex_lock(&data->update_lock);
647 638
@@ -650,32 +641,32 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
650 fan_nr = data->type == smsc47m2 ? 3 : 2; 641 fan_nr = data->type == smsc47m2 ? 3 : 2;
651 642
652 for (i = 0; i < fan_nr; i++) { 643 for (i = 0; i < fan_nr; i++) {
653 data->fan[i] = smsc47m1_read_value(client, 644 data->fan[i] = smsc47m1_read_value(data,
654 SMSC47M1_REG_FAN[i]); 645 SMSC47M1_REG_FAN[i]);
655 data->fan_preload[i] = smsc47m1_read_value(client, 646 data->fan_preload[i] = smsc47m1_read_value(data,
656 SMSC47M1_REG_FAN_PRELOAD[i]); 647 SMSC47M1_REG_FAN_PRELOAD[i]);
657 data->pwm[i] = smsc47m1_read_value(client, 648 data->pwm[i] = smsc47m1_read_value(data,
658 SMSC47M1_REG_PWM[i]); 649 SMSC47M1_REG_PWM[i]);
659 } 650 }
660 651
661 i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV); 652 i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
662 data->fan_div[0] = (i >> 4) & 0x03; 653 data->fan_div[0] = (i >> 4) & 0x03;
663 data->fan_div[1] = i >> 6; 654 data->fan_div[1] = i >> 6;
664 655
665 data->alarms = smsc47m1_read_value(client, 656 data->alarms = smsc47m1_read_value(data,
666 SMSC47M1_REG_ALARM) >> 6; 657 SMSC47M1_REG_ALARM) >> 6;
667 /* Clear alarms if needed */ 658 /* Clear alarms if needed */
668 if (data->alarms) 659 if (data->alarms)
669 smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0); 660 smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
670 661
671 if (fan_nr >= 3) { 662 if (fan_nr >= 3) {
672 data->fan_div[2] = (smsc47m1_read_value(client, 663 data->fan_div[2] = (smsc47m1_read_value(data,
673 SMSC47M2_REG_FANDIV3) >> 4) & 0x03; 664 SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
674 data->alarms |= (smsc47m1_read_value(client, 665 data->alarms |= (smsc47m1_read_value(data,
675 SMSC47M2_REG_ALARM6) & 0x40) >> 4; 666 SMSC47M2_REG_ALARM6) & 0x40) >> 4;
676 /* Clear alarm if needed */ 667 /* Clear alarm if needed */
677 if (data->alarms & 0x04) 668 if (data->alarms & 0x04)
678 smsc47m1_write_value(client, 669 smsc47m1_write_value(data,
679 SMSC47M2_REG_ALARM6, 670 SMSC47M2_REG_ALARM6,
680 0x40); 671 0x40);
681 } 672 }
@@ -687,18 +678,86 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
687 return data; 678 return data;
688} 679}
689 680
681static int __init smsc47m1_device_add(unsigned short address,
682 const struct smsc47m1_sio_data *sio_data)
683{
684 struct resource res = {
685 .start = address,
686 .end = address + SMSC_EXTENT - 1,
687 .name = DRVNAME,
688 .flags = IORESOURCE_IO,
689 };
690 int err;
691
692 pdev = platform_device_alloc(DRVNAME, address);
693 if (!pdev) {
694 err = -ENOMEM;
695 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
696 goto exit;
697 }
698
699 err = platform_device_add_resources(pdev, &res, 1);
700 if (err) {
701 printk(KERN_ERR DRVNAME ": Device resource addition failed "
702 "(%d)\n", err);
703 goto exit_device_put;
704 }
705
706 pdev->dev.platform_data = kmalloc(sizeof(struct smsc47m1_sio_data),
707 GFP_KERNEL);
708 if (!pdev->dev.platform_data) {
709 err = -ENOMEM;
710 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
711 goto exit_device_put;
712 }
713 memcpy(pdev->dev.platform_data, sio_data,
714 sizeof(struct smsc47m1_sio_data));
715
716 err = platform_device_add(pdev);
717 if (err) {
718 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
719 err);
720 goto exit_device_put;
721 }
722
723 return 0;
724
725exit_device_put:
726 platform_device_put(pdev);
727exit:
728 return err;
729}
730
690static int __init sm_smsc47m1_init(void) 731static int __init sm_smsc47m1_init(void)
691{ 732{
692 if (smsc47m1_find(&address)) { 733 int err;
734 unsigned short address;
735 struct smsc47m1_sio_data sio_data;
736
737 if (smsc47m1_find(&address, &sio_data))
693 return -ENODEV; 738 return -ENODEV;
694 }
695 739
696 return i2c_isa_add_driver(&smsc47m1_driver); 740 err = platform_driver_register(&smsc47m1_driver);
741 if (err)
742 goto exit;
743
744 /* Sets global pdev as a side effect */
745 err = smsc47m1_device_add(address, &sio_data);
746 if (err)
747 goto exit_driver;
748
749 return 0;
750
751exit_driver:
752 platform_driver_unregister(&smsc47m1_driver);
753exit:
754 return err;
697} 755}
698 756
699static void __exit sm_smsc47m1_exit(void) 757static void __exit sm_smsc47m1_exit(void)
700{ 758{
701 i2c_isa_del_driver(&smsc47m1_driver); 759 platform_device_unregister(pdev);
760 platform_driver_unregister(&smsc47m1_driver);
702} 761}
703 762
704MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); 763MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");