diff options
Diffstat (limited to 'drivers/hwmon/smsc47b397.c')
-rw-r--r-- | drivers/hwmon/smsc47b397.c | 86 |
1 files changed, 37 insertions, 49 deletions
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 251ac2659554..2a3e21b5b6b4 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -31,23 +31,14 @@ #include <linux/ioport.h> #include <linux/jiffies.h> #include <linux/i2c.h> -#include <linux/i2c-sensor.h> +#include <linux/i2c-isa.h> +#include <linux/hwmon.h> +#include <linux/err.h> #include <linux/init.h> #include <asm/io.h> -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; /* Address is autodetected, there is no default value */ -static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; -static struct i2c_force_data forces[] = {{NULL}}; - -enum chips { any_chip, smsc47b397 }; -static struct i2c_address_data addr_data = { - .normal_i2c = normal_i2c, - .normal_isa = normal_isa, - .probe = normal_i2c, /* cheat */ - .ignore = normal_i2c, /* cheat */ - .forces = forces, -}; +static unsigned short address; /* Super-I/0 registers and commands */ @@ -100,6 +91,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80}; struct smsc47b397_data { struct i2c_client client; + struct class_device *class_dev; struct semaphore lock; struct semaphore update_lock; @@ -215,64 +207,51 @@ sysfs_fan(4); #define device_create_file_fan(client, num) \ device_create_file(&client->dev, &dev_attr_fan##num##_input) -static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind); - -static int smsc47b397_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_detect(adapter, &addr_data, smsc47b397_detect); -} - static int smsc47b397_detach_client(struct i2c_client *client) { + struct smsc47b397_data *data = i2c_get_clientdata(client); int err; - if ((err = i2c_detach_client(client))) { - dev_err(&client->dev, "Client deregistration failed, " - "client not detached.\n"); + hwmon_device_unregister(data->class_dev); + + if ((err = i2c_detach_client(client))) return err; - } release_region(client->addr, SMSC_EXTENT); - kfree(i2c_get_clientdata(client)); + kfree(data); return 0; } +static int smsc47b397_detect(struct i2c_adapter *adapter); + static struct i2c_driver smsc47b397_driver = { .owner = THIS_MODULE, .name = "smsc47b397", - .id = I2C_DRIVERID_SMSC47B397, - .flags = I2C_DF_NOTIFY, - .attach_adapter = smsc47b397_attach_adapter, + .attach_adapter = smsc47b397_detect, .detach_client = smsc47b397_detach_client, }; -static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) +static int smsc47b397_detect(struct i2c_adapter *adapter) { struct i2c_client *new_client; struct smsc47b397_data *data; int err = 0; - if (!i2c_is_isa_adapter(adapter)) { - return 0; - } - - if (!request_region(addr, SMSC_EXTENT, smsc47b397_driver.name)) { - dev_err(&adapter->dev, "Region 0x%x already in use!\n", addr); + if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.name)) { + dev_err(&adapter->dev, "Region 0x%x already in use!\n", + address); return -EBUSY; } - if (!(data = kmalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) { + if (!(data = kzalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) { err = -ENOMEM; goto error_release; } - memset(data, 0x00, sizeof(struct smsc47b397_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); - new_client->addr = addr; + new_client->addr = address; init_MUTEX(&data->lock); new_client->adapter = adapter; new_client->driver = &smsc47b397_driver; @@ -285,6 +264,12 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) if ((err = i2c_attach_client(new_client))) goto error_free; + data->class_dev = hwmon_device_register(&new_client->dev); + if (IS_ERR(data->class_dev)) { + err = PTR_ERR(data->class_dev); + goto error_detach; + } + device_create_file_temp(new_client, 1); device_create_file_temp(new_client, 2); device_create_file_temp(new_client, 3); @@ -297,21 +282,23 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) return 0; +error_detach: + i2c_detach_client(new_client); error_free: - kfree(new_client); + kfree(data); error_release: - release_region(addr, SMSC_EXTENT); + release_region(address, SMSC_EXTENT); return err; } -static int __init smsc47b397_find(unsigned int *addr) +static int __init smsc47b397_find(unsigned short *addr) { u8 id, rev; superio_enter(); id = superio_inb(SUPERIO_REG_DEVID); - if (id != 0x6f) { + if ((id != 0x6f) && (id != 0x81)) { superio_exit(); return -ENODEV; } @@ -322,8 +309,9 @@ static int __init smsc47b397_find(unsigned int *addr) *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); - printk(KERN_INFO "smsc47b397: found SMSC LPC47B397-NC " - "(base address 0x%04x, revision %u)\n", *addr, rev); + printk(KERN_INFO "smsc47b397: found SMSC %s " + "(base address 0x%04x, revision %u)\n", + id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev); superio_exit(); return 0; @@ -333,15 +321,15 @@ static int __init smsc47b397_init(void) { int ret; - if ((ret = smsc47b397_find(normal_isa))) + if ((ret = smsc47b397_find(&address))) return ret; - return i2c_add_driver(&smsc47b397_driver); + return i2c_isa_add_driver(&smsc47b397_driver); } static void __exit smsc47b397_exit(void) { - i2c_del_driver(&smsc47b397_driver); + i2c_isa_del_driver(&smsc47b397_driver); } MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); |