aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/smsc47m1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/smsc47m1.c')
-rw-r--r--drivers/hwmon/smsc47m1.c70
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
37static 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 */
39static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; 40static unsigned short address;
40static struct i2c_force_data forces[] = {{NULL}};
41
42enum chips { any_chip, smsc47m1 };
43static 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
109struct smsc47m1_data { 102struct 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
124static int smsc47m1_attach_adapter(struct i2c_adapter *adapter); 118static int smsc47m1_detect(struct i2c_adapter *adapter);
125static int smsc47m1_find(int *address);
126static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind);
127static int smsc47m1_detach_client(struct i2c_client *client); 119static int smsc47m1_detach_client(struct i2c_client *client);
128 120
129static int smsc47m1_read_value(struct i2c_client *client, u8 reg); 121static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
@@ -136,9 +128,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
136static struct i2c_driver smsc47m1_driver = { 128static 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
355static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); 345static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
356 346
357static int smsc47m1_attach_adapter(struct i2c_adapter *adapter) 347static 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
364static 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
404static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) 387static 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
483error_detach:
484 i2c_detach_client(new_client);
497error_free: 485error_free:
498 kfree(data); 486 kfree(data);
499error_release: 487error_release:
@@ -503,16 +491,16 @@ error_release:
503 491
504static int smsc47m1_detach_client(struct i2c_client *client) 492static 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
574static int __init sm_smsc47m1_init(void) 562static 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
583static void __exit sm_smsc47m1_exit(void) 571static 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
588MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); 576MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");