diff options
Diffstat (limited to 'drivers/hwmon/asb100.c')
-rw-r--r-- | drivers/hwmon/asb100.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c index 70d996d6fe0a..3ab7a2ddafba 100644 --- a/drivers/hwmon/asb100.c +++ b/drivers/hwmon/asb100.c | |||
@@ -41,6 +41,8 @@ | |||
41 | #include <linux/i2c.h> | 41 | #include <linux/i2c.h> |
42 | #include <linux/i2c-sensor.h> | 42 | #include <linux/i2c-sensor.h> |
43 | #include <linux/i2c-vid.h> | 43 | #include <linux/i2c-vid.h> |
44 | #include <linux/hwmon.h> | ||
45 | #include <linux/err.h> | ||
44 | #include <linux/init.h> | 46 | #include <linux/init.h> |
45 | #include <linux/jiffies.h> | 47 | #include <linux/jiffies.h> |
46 | #include "lm75.h" | 48 | #include "lm75.h" |
@@ -183,6 +185,7 @@ static u8 DIV_TO_REG(long val) | |||
183 | dynamically allocated, at the same time the client itself is allocated. */ | 185 | dynamically allocated, at the same time the client itself is allocated. */ |
184 | struct asb100_data { | 186 | struct asb100_data { |
185 | struct i2c_client client; | 187 | struct i2c_client client; |
188 | struct class_device *class_dev; | ||
186 | struct semaphore lock; | 189 | struct semaphore lock; |
187 | enum chips type; | 190 | enum chips type; |
188 | 191 | ||
@@ -821,6 +824,12 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) | |||
821 | data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2)); | 824 | data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2)); |
822 | 825 | ||
823 | /* Register sysfs hooks */ | 826 | /* Register sysfs hooks */ |
827 | data->class_dev = hwmon_device_register(&new_client->dev); | ||
828 | if (IS_ERR(data->class_dev)) { | ||
829 | err = PTR_ERR(data->class_dev); | ||
830 | goto ERROR3; | ||
831 | } | ||
832 | |||
824 | device_create_file_in(new_client, 0); | 833 | device_create_file_in(new_client, 0); |
825 | device_create_file_in(new_client, 1); | 834 | device_create_file_in(new_client, 1); |
826 | device_create_file_in(new_client, 2); | 835 | device_create_file_in(new_client, 2); |
@@ -847,6 +856,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) | |||
847 | 856 | ||
848 | return 0; | 857 | return 0; |
849 | 858 | ||
859 | ERROR3: | ||
860 | i2c_detach_client(data->lm75[1]); | ||
861 | i2c_detach_client(data->lm75[0]); | ||
862 | kfree(data->lm75[1]); | ||
863 | kfree(data->lm75[0]); | ||
850 | ERROR2: | 864 | ERROR2: |
851 | i2c_detach_client(new_client); | 865 | i2c_detach_client(new_client); |
852 | ERROR1: | 866 | ERROR1: |
@@ -857,21 +871,26 @@ ERROR0: | |||
857 | 871 | ||
858 | static int asb100_detach_client(struct i2c_client *client) | 872 | static int asb100_detach_client(struct i2c_client *client) |
859 | { | 873 | { |
874 | struct asb100_data *data = i2c_get_clientdata(client); | ||
860 | int err; | 875 | int err; |
861 | 876 | ||
877 | /* main client */ | ||
878 | if (data) | ||
879 | hwmon_device_unregister(data->class_dev); | ||
880 | |||
862 | if ((err = i2c_detach_client(client))) { | 881 | if ((err = i2c_detach_client(client))) { |
863 | dev_err(&client->dev, "client deregistration failed; " | 882 | dev_err(&client->dev, "client deregistration failed; " |
864 | "client not detached.\n"); | 883 | "client not detached.\n"); |
865 | return err; | 884 | return err; |
866 | } | 885 | } |
867 | 886 | ||
868 | if (i2c_get_clientdata(client)==NULL) { | 887 | /* main client */ |
869 | /* subclients */ | 888 | if (data) |
889 | kfree(data); | ||
890 | |||
891 | /* subclient */ | ||
892 | else | ||
870 | kfree(client); | 893 | kfree(client); |
871 | } else { | ||
872 | /* main client */ | ||
873 | kfree(i2c_get_clientdata(client)); | ||
874 | } | ||
875 | 894 | ||
876 | return 0; | 895 | return 0; |
877 | } | 896 | } |