diff options
Diffstat (limited to 'drivers/hwmon/smsc47m1.c')
-rw-r--r-- | drivers/hwmon/smsc47m1.c | 70 |
1 files changed, 29 insertions, 41 deletions
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 7166ad0b2fda..7e699a8ede26 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -30,21 +30,14 @@ | |||
30 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
31 | #include <linux/jiffies.h> | 31 | #include <linux/jiffies.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
33 | #include <linux/i2c-sensor.h> | 33 | #include <linux/i2c-isa.h> |
34 | #include <linux/hwmon.h> | ||
35 | #include <linux/err.h> | ||
34 | #include <linux/init.h> | 36 | #include <linux/init.h> |
35 | #include <asm/io.h> | 37 | #include <asm/io.h> |
36 | 38 | ||
37 | static unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
38 | /* Address is autodetected, there is no default value */ | 39 | /* Address is autodetected, there is no default value */ |
39 | static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; | 40 | static unsigned short address; |
40 | static struct i2c_force_data forces[] = {{NULL}}; | ||
41 | |||
42 | enum chips { any_chip, smsc47m1 }; | ||
43 | static struct i2c_address_data addr_data = { | ||
44 | .normal_i2c = normal_i2c, | ||
45 | .normal_isa = normal_isa, | ||
46 | .forces = forces, | ||
47 | }; | ||
48 | 41 | ||
49 | /* Super-I/0 registers and commands */ | 42 | /* Super-I/0 registers and commands */ |
50 | 43 | ||
@@ -108,6 +101,7 @@ superio_exit(void) | |||
108 | 101 | ||
109 | struct smsc47m1_data { | 102 | struct smsc47m1_data { |
110 | struct i2c_client client; | 103 | struct i2c_client client; |
104 | struct class_device *class_dev; | ||
111 | struct semaphore lock; | 105 | struct semaphore lock; |
112 | 106 | ||
113 | struct semaphore update_lock; | 107 | struct semaphore update_lock; |
@@ -121,9 +115,7 @@ struct smsc47m1_data { | |||
121 | }; | 115 | }; |
122 | 116 | ||
123 | 117 | ||
124 | static int smsc47m1_attach_adapter(struct i2c_adapter *adapter); | 118 | static int smsc47m1_detect(struct i2c_adapter *adapter); |
125 | static int smsc47m1_find(int *address); | ||
126 | static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind); | ||
127 | static int smsc47m1_detach_client(struct i2c_client *client); | 119 | static int smsc47m1_detach_client(struct i2c_client *client); |
128 | 120 | ||
129 | static int smsc47m1_read_value(struct i2c_client *client, u8 reg); | 121 | static int smsc47m1_read_value(struct i2c_client *client, u8 reg); |
@@ -136,9 +128,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, | |||
136 | static struct i2c_driver smsc47m1_driver = { | 128 | static struct i2c_driver smsc47m1_driver = { |
137 | .owner = THIS_MODULE, | 129 | .owner = THIS_MODULE, |
138 | .name = "smsc47m1", | 130 | .name = "smsc47m1", |
139 | .id = I2C_DRIVERID_SMSC47M1, | 131 | .attach_adapter = smsc47m1_detect, |
140 | .flags = I2C_DF_NOTIFY, | ||
141 | .attach_adapter = smsc47m1_attach_adapter, | ||
142 | .detach_client = smsc47m1_detach_client, | 132 | .detach_client = smsc47m1_detach_client, |
143 | }; | 133 | }; |
144 | 134 | ||
@@ -354,14 +344,7 @@ fan_present(2); | |||
354 | 344 | ||
355 | static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); | 345 | static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); |
356 | 346 | ||
357 | static int smsc47m1_attach_adapter(struct i2c_adapter *adapter) | 347 | static int __init smsc47m1_find(unsigned short *addr) |
358 | { | ||
359 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
360 | return 0; | ||
361 | return i2c_detect(adapter, &addr_data, smsc47m1_detect); | ||
362 | } | ||
363 | |||
364 | static int smsc47m1_find(int *address) | ||
365 | { | 348 | { |
366 | u8 val; | 349 | u8 val; |
367 | 350 | ||
@@ -388,10 +371,10 @@ static int smsc47m1_find(int *address) | |||
388 | } | 371 | } |
389 | 372 | ||
390 | superio_select(); | 373 | superio_select(); |
391 | *address = (superio_inb(SUPERIO_REG_BASE) << 8) | 374 | *addr = (superio_inb(SUPERIO_REG_BASE) << 8) |
392 | | superio_inb(SUPERIO_REG_BASE + 1); | 375 | | superio_inb(SUPERIO_REG_BASE + 1); |
393 | val = superio_inb(SUPERIO_REG_ACT); | 376 | val = superio_inb(SUPERIO_REG_ACT); |
394 | if (*address == 0 || (val & 0x01) == 0) { | 377 | if (*addr == 0 || (val & 0x01) == 0) { |
395 | printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n"); | 378 | printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n"); |
396 | superio_exit(); | 379 | superio_exit(); |
397 | return -ENODEV; | 380 | return -ENODEV; |
@@ -401,17 +384,13 @@ static int smsc47m1_find(int *address) | |||
401 | return 0; | 384 | return 0; |
402 | } | 385 | } |
403 | 386 | ||
404 | static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) | 387 | static int smsc47m1_detect(struct i2c_adapter *adapter) |
405 | { | 388 | { |
406 | struct i2c_client *new_client; | 389 | struct i2c_client *new_client; |
407 | struct smsc47m1_data *data; | 390 | struct smsc47m1_data *data; |
408 | int err = 0; | 391 | int err = 0; |
409 | int fan1, fan2, pwm1, pwm2; | 392 | int fan1, fan2, pwm1, pwm2; |
410 | 393 | ||
411 | if (!i2c_is_isa_adapter(adapter)) { | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) { | 394 | if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) { |
416 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); | 395 | dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); |
417 | return -EBUSY; | 396 | return -EBUSY; |
@@ -461,6 +440,13 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) | |||
461 | function. */ | 440 | function. */ |
462 | smsc47m1_update_device(&new_client->dev, 1); | 441 | smsc47m1_update_device(&new_client->dev, 1); |
463 | 442 | ||
443 | /* Register sysfs hooks */ | ||
444 | data->class_dev = hwmon_device_register(&new_client->dev); | ||
445 | if (IS_ERR(data->class_dev)) { | ||
446 | err = PTR_ERR(data->class_dev); | ||
447 | goto error_detach; | ||
448 | } | ||
449 | |||
464 | if (fan1) { | 450 | if (fan1) { |
465 | device_create_file(&new_client->dev, &dev_attr_fan1_input); | 451 | device_create_file(&new_client->dev, &dev_attr_fan1_input); |
466 | device_create_file(&new_client->dev, &dev_attr_fan1_min); | 452 | device_create_file(&new_client->dev, &dev_attr_fan1_min); |
@@ -494,6 +480,8 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) | |||
494 | 480 | ||
495 | return 0; | 481 | return 0; |
496 | 482 | ||
483 | error_detach: | ||
484 | i2c_detach_client(new_client); | ||
497 | error_free: | 485 | error_free: |
498 | kfree(data); | 486 | kfree(data); |
499 | error_release: | 487 | error_release: |
@@ -503,16 +491,16 @@ error_release: | |||
503 | 491 | ||
504 | static int smsc47m1_detach_client(struct i2c_client *client) | 492 | static int smsc47m1_detach_client(struct i2c_client *client) |
505 | { | 493 | { |
494 | struct smsc47m1_data *data = i2c_get_clientdata(client); | ||
506 | int err; | 495 | int err; |
507 | 496 | ||
508 | if ((err = i2c_detach_client(client))) { | 497 | hwmon_device_unregister(data->class_dev); |
509 | dev_err(&client->dev, "Client deregistration failed, " | 498 | |
510 | "client not detached.\n"); | 499 | if ((err = i2c_detach_client(client))) |
511 | return err; | 500 | return err; |
512 | } | ||
513 | 501 | ||
514 | release_region(client->addr, SMSC_EXTENT); | 502 | release_region(client->addr, SMSC_EXTENT); |
515 | kfree(i2c_get_clientdata(client)); | 503 | kfree(data); |
516 | 504 | ||
517 | return 0; | 505 | return 0; |
518 | } | 506 | } |
@@ -573,16 +561,16 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, | |||
573 | 561 | ||
574 | static int __init sm_smsc47m1_init(void) | 562 | static int __init sm_smsc47m1_init(void) |
575 | { | 563 | { |
576 | if (smsc47m1_find(normal_isa)) { | 564 | if (smsc47m1_find(&address)) { |
577 | return -ENODEV; | 565 | return -ENODEV; |
578 | } | 566 | } |
579 | 567 | ||
580 | return i2c_add_driver(&smsc47m1_driver); | 568 | return i2c_isa_add_driver(&smsc47m1_driver); |
581 | } | 569 | } |
582 | 570 | ||
583 | static void __exit sm_smsc47m1_exit(void) | 571 | static void __exit sm_smsc47m1_exit(void) |
584 | { | 572 | { |
585 | i2c_del_driver(&smsc47m1_driver); | 573 | i2c_isa_del_driver(&smsc47m1_driver); |
586 | } | 574 | } |
587 | 575 | ||
588 | MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); | 576 | MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); |