提交 943b0830 编写于 作者: M Mark M. Hoffman 提交者: Greg Kroah-Hartman

[PATCH] I2C hwmon: add hwmon sysfs class to drivers

This patch modifies sensors chip drivers to make use of the new
sysfs class "hwmon".
Signed-off-by: NMark M. Hoffman <mhoffman@lightlink.com>
Signed-off-by: NJean Delvare <khali@linux-fr.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 1236441f
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
...@@ -89,6 +91,7 @@ clearing it. Weird, ey? --Phil */ ...@@ -89,6 +91,7 @@ clearing it. Weird, ey? --Phil */
/* Each client has this additional data */ /* Each client has this additional data */
struct adm1021_data { struct adm1021_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
enum chips type; enum chips type;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -295,6 +298,12 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -295,6 +298,12 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
adm1021_init_client(new_client); adm1021_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error2;
}
device_create_file(&new_client->dev, &dev_attr_temp1_max); device_create_file(&new_client->dev, &dev_attr_temp1_max);
device_create_file(&new_client->dev, &dev_attr_temp1_min); device_create_file(&new_client->dev, &dev_attr_temp1_min);
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
...@@ -305,6 +314,8 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -305,6 +314,8 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
error2:
i2c_detach_client(new_client);
error1: error1:
kfree(data); kfree(data);
error0: error0:
...@@ -322,14 +333,17 @@ static void adm1021_init_client(struct i2c_client *client) ...@@ -322,14 +333,17 @@ static void adm1021_init_client(struct i2c_client *client)
static int adm1021_detach_client(struct i2c_client *client) static int adm1021_detach_client(struct i2c_client *client)
{ {
struct adm1021_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, client not detached.\n"); dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -132,6 +134,7 @@ static struct i2c_driver adm1025_driver = { ...@@ -132,6 +134,7 @@ static struct i2c_driver adm1025_driver = {
struct adm1025_data { struct adm1025_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -416,6 +419,12 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -416,6 +419,12 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
adm1025_init_client(new_client); adm1025_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
device_create_file(&new_client->dev, &dev_attr_in2_input); device_create_file(&new_client->dev, &dev_attr_in2_input);
...@@ -452,6 +461,8 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -452,6 +461,8 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -502,15 +513,18 @@ static void adm1025_init_client(struct i2c_client *client) ...@@ -502,15 +513,18 @@ static void adm1025_init_client(struct i2c_client *client)
static int adm1025_detach_client(struct i2c_client *client) static int adm1025_detach_client(struct i2c_client *client)
{ {
struct adm1025_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
...@@ -259,6 +261,7 @@ struct pwm_data { ...@@ -259,6 +261,7 @@ struct pwm_data {
struct adm1026_data { struct adm1026_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -324,8 +327,10 @@ int adm1026_attach_adapter(struct i2c_adapter *adapter) ...@@ -324,8 +327,10 @@ int adm1026_attach_adapter(struct i2c_adapter *adapter)
int adm1026_detach_client(struct i2c_client *client) int adm1026_detach_client(struct i2c_client *client)
{ {
struct adm1026_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
i2c_detach_client(client); i2c_detach_client(client);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -1555,6 +1560,12 @@ int adm1026_detect(struct i2c_adapter *adapter, int address, ...@@ -1555,6 +1560,12 @@ int adm1026_detect(struct i2c_adapter *adapter, int address,
adm1026_init_client(new_client); adm1026_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exitdetach;
}
device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
...@@ -1690,6 +1701,8 @@ int adm1026_detect(struct i2c_adapter *adapter, int address, ...@@ -1690,6 +1701,8 @@ int adm1026_detect(struct i2c_adapter *adapter, int address,
return 0; return 0;
/* Error out and cleanup code */ /* Error out and cleanup code */
exitdetach:
i2c_detach_client(new_client);
exitfree: exitfree:
kfree(data); kfree(data);
exit: exit:
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Following macros takes channel parameter starting from 0 to 2 */ /* Following macros takes channel parameter starting from 0 to 2 */
#define ADM1031_REG_FAN_SPEED(nr) (0x08 + (nr)) #define ADM1031_REG_FAN_SPEED(nr) (0x08 + (nr))
...@@ -69,6 +71,7 @@ typedef u8 auto_chan_table_t[8][2]; ...@@ -69,6 +71,7 @@ typedef u8 auto_chan_table_t[8][2];
/* Each client has this additional data */ /* Each client has this additional data */
struct adm1031_data { struct adm1031_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
int chip_type; int chip_type;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
...@@ -788,6 +791,12 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -788,6 +791,12 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
adm1031_init_client(new_client); adm1031_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_fan1_input); device_create_file(&new_client->dev, &dev_attr_fan1_input);
device_create_file(&new_client->dev, &dev_attr_fan1_div); device_create_file(&new_client->dev, &dev_attr_fan1_div);
device_create_file(&new_client->dev, &dev_attr_fan1_min); device_create_file(&new_client->dev, &dev_attr_fan1_min);
...@@ -833,6 +842,8 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -833,6 +842,8 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -841,11 +852,14 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -841,11 +852,14 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
static int adm1031_detach_client(struct i2c_client *client) static int adm1031_detach_client(struct i2c_client *client)
{ {
struct adm1031_data *data = i2c_get_clientdata(client);
int ret; int ret;
hwmon_device_unregister(data->class_dev);
if ((ret = i2c_detach_client(client)) != 0) { if ((ret = i2c_detach_client(client)) != 0) {
return ret; return ret;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
...@@ -150,6 +152,7 @@ static struct i2c_driver adm9240_driver = { ...@@ -150,6 +152,7 @@ static struct i2c_driver adm9240_driver = {
struct adm9240_data { struct adm9240_data {
enum chips type; enum chips type;
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; char valid;
unsigned long last_updated_measure; unsigned long last_updated_measure;
...@@ -582,6 +585,12 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -582,6 +585,12 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
adm9240_init_client(new_client); adm9240_init_client(new_client);
/* populate sysfs filesystem */ /* populate sysfs filesystem */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in0_min); device_create_file(&new_client->dev, &dev_attr_in0_min);
device_create_file(&new_client->dev, &dev_attr_in0_max); device_create_file(&new_client->dev, &dev_attr_in0_max);
...@@ -615,6 +624,9 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -615,6 +624,9 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_cpu0_vid); device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -630,15 +642,18 @@ static int adm9240_attach_adapter(struct i2c_adapter *adapter) ...@@ -630,15 +642,18 @@ static int adm9240_attach_adapter(struct i2c_adapter *adapter)
static int adm9240_detach_client(struct i2c_client *client) static int adm9240_detach_client(struct i2c_client *client)
{ {
struct adm9240_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include "lm75.h" #include "lm75.h"
...@@ -183,6 +185,7 @@ static u8 DIV_TO_REG(long val) ...@@ -183,6 +185,7 @@ static u8 DIV_TO_REG(long val)
dynamically allocated, at the same time the client itself is allocated. */ dynamically allocated, at the same time the client itself is allocated. */
struct asb100_data { struct asb100_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -821,6 +824,12 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -821,6 +824,12 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2)); data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2));
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
device_create_file_in(new_client, 1); device_create_file_in(new_client, 1);
device_create_file_in(new_client, 2); device_create_file_in(new_client, 2);
...@@ -847,6 +856,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -847,6 +856,11 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR3:
i2c_detach_client(data->lm75[1]);
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[1]);
kfree(data->lm75[0]);
ERROR2: ERROR2:
i2c_detach_client(new_client); i2c_detach_client(new_client);
ERROR1: ERROR1:
...@@ -857,21 +871,26 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -857,21 +871,26 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
static int asb100_detach_client(struct i2c_client *client) static int asb100_detach_client(struct i2c_client *client)
{ {
struct asb100_data *data = i2c_get_clientdata(client);
int err; int err;
/* main client */
if (data)
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "client deregistration failed; " dev_err(&client->dev, "client deregistration failed; "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
if (i2c_get_clientdata(client)==NULL) { /* main client */
/* subclients */ if (data)
kfree(data);
/* subclient */
else
kfree(client); kfree(client);
} else {
/* main client */
kfree(i2c_get_clientdata(client));
}
return 0; return 0;
} }
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("System voltages control via Attansic ATXP1"); MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
...@@ -59,6 +61,7 @@ static struct i2c_driver atxp1_driver = { ...@@ -59,6 +61,7 @@ static struct i2c_driver atxp1_driver = {
struct atxp1_data { struct atxp1_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
unsigned long last_updated; unsigned long last_updated;
u8 valid; u8 valid;
...@@ -317,6 +320,12 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -317,6 +320,12 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_free; goto exit_free;
} }
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_gpio1); device_create_file(&new_client->dev, &dev_attr_gpio1);
device_create_file(&new_client->dev, &dev_attr_gpio2); device_create_file(&new_client->dev, &dev_attr_gpio2);
device_create_file(&new_client->dev, &dev_attr_cpu0_vid); device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
...@@ -326,6 +335,8 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -326,6 +335,8 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -334,14 +345,17 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -334,14 +345,17 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
static int atxp1_detach_client(struct i2c_client * client) static int atxp1_detach_client(struct i2c_client * client)
{ {
struct atxp1_data * data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
err = i2c_detach_client(client); err = i2c_detach_client(client);
if (err) if (err)
dev_err(&client->dev, "Failed to detach client.\n"); dev_err(&client->dev, "Failed to detach client.\n");
else else
kfree(i2c_get_clientdata(client)); kfree(data);
return err; return err;
}; };
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include "lm75.h" #include "lm75.h"
/* Addresses to scan */ /* Addresses to scan */
...@@ -71,6 +73,7 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low") ...@@ -71,6 +73,7 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low")
/* Each client has this additional data */ /* Each client has this additional data */
struct ds1621_data { struct ds1621_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -250,6 +253,12 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, ...@@ -250,6 +253,12 @@ int ds1621_detect(struct i2c_adapter *adapter, int address,
ds1621_init_client(new_client); ds1621_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_alarms);
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_min); device_create_file(&new_client->dev, &dev_attr_temp1_min);
...@@ -259,6 +268,8 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, ...@@ -259,6 +268,8 @@ int ds1621_detect(struct i2c_adapter *adapter, int address,
/* OK, this is not exactly good programming practice, usually. But it is /* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */ very code-efficient in this case. */
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -267,15 +278,18 @@ int ds1621_detect(struct i2c_adapter *adapter, int address, ...@@ -267,15 +278,18 @@ int ds1621_detect(struct i2c_adapter *adapter, int address,
static int ds1621_detach_client(struct i2c_client *client) static int ds1621_detach_client(struct i2c_client *client)
{ {
struct ds1621_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -132,6 +134,7 @@ static struct i2c_driver fscher_driver = { ...@@ -132,6 +134,7 @@ static struct i2c_driver fscher_driver = {
struct fscher_data { struct fscher_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -341,6 +344,12 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -341,6 +344,12 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
fscher_init_client(new_client); fscher_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file_revision(new_client); device_create_file_revision(new_client);
device_create_file_alarms(new_client); device_create_file_alarms(new_client);
device_create_file_control(new_client); device_create_file_control(new_client);
...@@ -360,6 +369,8 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -360,6 +369,8 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -368,15 +379,18 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -368,15 +379,18 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
static int fscher_detach_client(struct i2c_client *client) static int fscher_detach_client(struct i2c_client *client)
{ {
struct fscher_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -113,6 +115,7 @@ static struct i2c_driver fscpos_driver = { ...@@ -113,6 +115,7 @@ static struct i2c_driver fscpos_driver = {
*/ */
struct fscpos_data { struct fscpos_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* 0 until following fields are valid */ char valid; /* 0 until following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -496,6 +499,12 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -496,6 +499,12 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision); dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_event); device_create_file(&new_client->dev, &dev_attr_event);
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
...@@ -526,6 +535,8 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -526,6 +535,8 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -534,14 +545,17 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -534,14 +545,17 @@ int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
static int fscpos_detach_client(struct i2c_client *client) static int fscpos_detach_client(struct i2c_client *client)
{ {
struct fscpos_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, client" dev_err(&client->dev, "Client deregistration failed, client"
" not detached.\n"); " not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
...@@ -117,6 +119,7 @@ static inline u8 FAN_TO_REG(long rpm, int div) ...@@ -117,6 +119,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
/* Each client has this additional data */ /* Each client has this additional data */
struct gl518_data { struct gl518_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
enum chips type; enum chips type;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -419,6 +422,12 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -419,6 +422,12 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
gl518_init_client((struct i2c_client *) new_client); gl518_init_client((struct i2c_client *) new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
device_create_file(&new_client->dev, &dev_attr_in2_input); device_create_file(&new_client->dev, &dev_attr_in2_input);
...@@ -450,6 +459,8 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -450,6 +459,8 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
/* OK, this is not exactly good programming practice, usually. But it is /* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */ very code-efficient in this case. */
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -477,16 +488,18 @@ static void gl518_init_client(struct i2c_client *client) ...@@ -477,16 +488,18 @@ static void gl518_init_client(struct i2c_client *client)
static int gl518_detach_client(struct i2c_client *client) static int gl518_detach_client(struct i2c_client *client)
{ {
struct gl518_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Type of the extra sensor */ /* Type of the extra sensor */
static unsigned short extra_sensor_type; static unsigned short extra_sensor_type;
...@@ -120,6 +122,7 @@ static struct i2c_driver gl520_driver = { ...@@ -120,6 +122,7 @@ static struct i2c_driver gl520_driver = {
/* Client data */ /* Client data */
struct gl520_data { struct gl520_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until the following fields are valid */ char valid; /* zero until the following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -571,6 +574,12 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -571,6 +574,12 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
gl520_init_client(new_client); gl520_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file_vid(new_client, 0); device_create_file_vid(new_client, 0);
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
...@@ -592,6 +601,8 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -592,6 +601,8 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -639,15 +650,18 @@ static void gl520_init_client(struct i2c_client *client) ...@@ -639,15 +650,18 @@ static void gl520_init_client(struct i2c_client *client)
static int gl520_detach_client(struct i2c_client *client) static int gl520_detach_client(struct i2c_client *client)
{ {
struct gl520_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -192,6 +194,7 @@ static int DIV_TO_REG(int val) ...@@ -192,6 +194,7 @@ static int DIV_TO_REG(int val)
allocated. */ allocated. */
struct it87_data { struct it87_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -840,6 +843,12 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -840,6 +843,12 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
it87_init_client(new_client, data); it87_init_client(new_client, data);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr); device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
...@@ -904,6 +913,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -904,6 +913,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR3:
i2c_detach_client(new_client);
ERROR2: ERROR2:
kfree(data); kfree(data);
ERROR1: ERROR1:
...@@ -915,8 +926,11 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -915,8 +926,11 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
static int it87_detach_client(struct i2c_client *client) static int it87_detach_client(struct i2c_client *client)
{ {
struct it87_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); "Client deregistration failed, client not detached.\n");
...@@ -925,7 +939,7 @@ static int it87_detach_client(struct i2c_client *client) ...@@ -925,7 +939,7 @@ static int it87_detach_client(struct i2c_client *client)
if(i2c_is_isa_client(client)) if(i2c_is_isa_client(client))
release_region(client->addr, IT87_EXTENT); release_region(client->addr, IT87_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -152,6 +154,7 @@ static struct i2c_driver lm63_driver = { ...@@ -152,6 +154,7 @@ static struct i2c_driver lm63_driver = {
struct lm63_data { struct lm63_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -437,6 +440,12 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -437,6 +440,12 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
lm63_init_client(new_client); lm63_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
if (data->config & 0x04) { /* tachometer enabled */ if (data->config & 0x04) { /* tachometer enabled */
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_fan1_input.dev_attr); &sensor_dev_attr_fan1_input.dev_attr);
...@@ -462,6 +471,8 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -462,6 +471,8 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -505,15 +516,18 @@ static void lm63_init_client(struct i2c_client *client) ...@@ -505,15 +516,18 @@ static void lm63_init_client(struct i2c_client *client)
static int lm63_detach_client(struct i2c_client *client) static int lm63_detach_client(struct i2c_client *client)
{ {
struct lm63_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached\n"); "client not detached\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include "lm75.h" #include "lm75.h"
...@@ -46,6 +48,7 @@ SENSORS_INSMOD_1(lm75); ...@@ -46,6 +48,7 @@ SENSORS_INSMOD_1(lm75);
/* Each client has this additional data */ /* Each client has this additional data */
struct lm75_data { struct lm75_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -208,12 +211,20 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -208,12 +211,20 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
lm75_init_client(new_client); lm75_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_max); device_create_file(&new_client->dev, &dev_attr_temp1_max);
device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -222,8 +233,10 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -222,8 +233,10 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm75_detach_client(struct i2c_client *client) static int lm75_detach_client(struct i2c_client *client)
{ {
struct lm75_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
i2c_detach_client(client); i2c_detach_client(client);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END };
...@@ -51,6 +52,7 @@ SENSORS_INSMOD_1(lm77); ...@@ -51,6 +52,7 @@ SENSORS_INSMOD_1(lm77);
/* Each client has this additional data */ /* Each client has this additional data */
struct lm77_data { struct lm77_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; char valid;
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -317,6 +319,12 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -317,6 +319,12 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
lm77_init_client(new_client); lm77_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_crit); device_create_file(&new_client->dev, &dev_attr_temp1_crit);
device_create_file(&new_client->dev, &dev_attr_temp1_min); device_create_file(&new_client->dev, &dev_attr_temp1_min);
...@@ -327,6 +335,8 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -327,6 +335,8 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_alarms);
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -335,8 +345,10 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -335,8 +345,10 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm77_detach_client(struct i2c_client *client) static int lm77_detach_client(struct i2c_client *client)
{ {
struct lm77_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
i2c_detach_client(client); i2c_detach_client(client);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
/* Addresses to scan */ /* Addresses to scan */
...@@ -134,6 +136,7 @@ static inline int VID_FROM_REG(u8 val) ...@@ -134,6 +136,7 @@ static inline int VID_FROM_REG(u8 val)
allocated. */ allocated. */
struct lm78_data { struct lm78_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -602,6 +605,12 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -602,6 +605,12 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
} }
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in0_min); device_create_file(&new_client->dev, &dev_attr_in0_min);
device_create_file(&new_client->dev, &dev_attr_in0_max); device_create_file(&new_client->dev, &dev_attr_in0_max);
...@@ -640,6 +649,8 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -640,6 +649,8 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR3:
i2c_detach_client(new_client);
ERROR2: ERROR2:
kfree(data); kfree(data);
ERROR1: ERROR1:
...@@ -651,8 +662,11 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -651,8 +662,11 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm78_detach_client(struct i2c_client *client) static int lm78_detach_client(struct i2c_client *client)
{ {
struct lm78_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); "Client deregistration failed, client not detached.\n");
...@@ -662,7 +676,7 @@ static int lm78_detach_client(struct i2c_client *client) ...@@ -662,7 +676,7 @@ static int lm78_detach_client(struct i2c_client *client)
if(i2c_is_isa_client(client)) if(i2c_is_isa_client(client))
release_region(client->addr, LM78_EXTENT); release_region(client->addr, LM78_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c,
...@@ -107,6 +109,7 @@ static inline long TEMP_FROM_REG(u16 temp) ...@@ -107,6 +109,7 @@ static inline long TEMP_FROM_REG(u16 temp)
struct lm80_data { struct lm80_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -451,6 +454,12 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -451,6 +454,12 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2)); data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2));
/* Register sysfs hooks */ /* Register sysfs hooks */
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(&new_client->dev, &dev_attr_in0_min); device_create_file(&new_client->dev, &dev_attr_in0_min);
device_create_file(&new_client->dev, &dev_attr_in1_min); device_create_file(&new_client->dev, &dev_attr_in1_min);
device_create_file(&new_client->dev, &dev_attr_in2_min); device_create_file(&new_client->dev, &dev_attr_in2_min);
...@@ -487,6 +496,8 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -487,6 +496,8 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
error_detach:
i2c_detach_client(new_client);
error_free: error_free:
kfree(data); kfree(data);
exit: exit:
...@@ -495,15 +506,18 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -495,15 +506,18 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm80_detach_client(struct i2c_client *client) static int lm80_detach_client(struct i2c_client *client)
{ {
struct lm80_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -138,6 +140,7 @@ static struct i2c_driver lm83_driver = { ...@@ -138,6 +140,7 @@ static struct i2c_driver lm83_driver = {
struct lm83_data { struct lm83_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -312,6 +315,12 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -312,6 +315,12 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
*/ */
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp1_input.dev_attr); &sensor_dev_attr_temp1_input.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
...@@ -340,6 +349,8 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -340,6 +349,8 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -348,15 +359,18 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -348,15 +359,18 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
static int lm83_detach_client(struct i2c_client *client) static int lm83_detach_client(struct i2c_client *client)
{ {
struct lm83_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); "Client deregistration failed, client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* Addresses to scan */ /* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
...@@ -339,6 +341,7 @@ struct lm85_autofan { ...@@ -339,6 +341,7 @@ struct lm85_autofan {
struct lm85_data { struct lm85_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -1166,6 +1169,12 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1166,6 +1169,12 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
lm85_init_client(new_client); lm85_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR2;
}
device_create_file(&new_client->dev, &dev_attr_fan1_input); device_create_file(&new_client->dev, &dev_attr_fan1_input);
device_create_file(&new_client->dev, &dev_attr_fan2_input); device_create_file(&new_client->dev, &dev_attr_fan2_input);
device_create_file(&new_client->dev, &dev_attr_fan3_input); device_create_file(&new_client->dev, &dev_attr_fan3_input);
...@@ -1235,6 +1244,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1235,6 +1244,8 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
return 0; return 0;
/* Error out and cleanup code */ /* Error out and cleanup code */
ERROR2:
i2c_detach_client(new_client);
ERROR1: ERROR1:
kfree(data); kfree(data);
ERROR0: ERROR0:
...@@ -1243,8 +1254,10 @@ int lm85_detect(struct i2c_adapter *adapter, int address, ...@@ -1243,8 +1254,10 @@ int lm85_detect(struct i2c_adapter *adapter, int address,
int lm85_detach_client(struct i2c_client *client) int lm85_detach_client(struct i2c_client *client)
{ {
struct lm85_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->class_dev);
i2c_detach_client(client); i2c_detach_client(client);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -59,6 +59,8 @@ ...@@ -59,6 +59,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -175,6 +177,7 @@ static struct i2c_driver lm87_driver = { ...@@ -175,6 +177,7 @@ static struct i2c_driver lm87_driver = {
struct lm87_data { struct lm87_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -608,6 +611,12 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -608,6 +611,12 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
data->in_scale[7] = 1875; data->in_scale[7] = 1875;
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
device_create_file(&new_client->dev, &dev_attr_in1_min); device_create_file(&new_client->dev, &dev_attr_in1_min);
device_create_file(&new_client->dev, &dev_attr_in1_max); device_create_file(&new_client->dev, &dev_attr_in1_max);
...@@ -673,6 +682,8 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -673,6 +682,8 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -719,15 +730,18 @@ static void lm87_init_client(struct i2c_client *client) ...@@ -719,15 +730,18 @@ static void lm87_init_client(struct i2c_client *client)
static int lm87_detach_client(struct i2c_client *client) static int lm87_detach_client(struct i2c_client *client)
{ {
struct lm87_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -77,6 +77,8 @@ ...@@ -77,6 +77,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* /*
* Addresses to scan * Addresses to scan
...@@ -200,6 +202,7 @@ static struct i2c_driver lm90_driver = { ...@@ -200,6 +202,7 @@ static struct i2c_driver lm90_driver = {
struct lm90_data { struct lm90_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -500,6 +503,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -500,6 +503,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
lm90_init_client(new_client); lm90_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
&sensor_dev_attr_temp1_input.dev_attr); &sensor_dev_attr_temp1_input.dev_attr);
device_create_file(&new_client->dev, device_create_file(&new_client->dev,
...@@ -524,6 +533,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -524,6 +533,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -547,15 +558,18 @@ static void lm90_init_client(struct i2c_client *client) ...@@ -547,15 +558,18 @@ static void lm90_init_client(struct i2c_client *client)
static int lm90_detach_client(struct i2c_client *client) static int lm90_detach_client(struct i2c_client *client)
{ {
struct lm90_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -45,7 +45,8 @@ ...@@ -45,7 +45,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* The LM92 and MAX6635 have 2 two-state pins for address selection, /* The LM92 and MAX6635 have 2 two-state pins for address selection,
resulting in 4 possible addresses. */ resulting in 4 possible addresses. */
...@@ -96,6 +97,7 @@ static struct i2c_driver lm92_driver; ...@@ -96,6 +97,7 @@ static struct i2c_driver lm92_driver;
/* Client data (each client gets its own) */ /* Client data (each client gets its own) */
struct lm92_data { struct lm92_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -359,6 +361,12 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -359,6 +361,12 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
lm92_init_client(new_client); lm92_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_crit); device_create_file(&new_client->dev, &dev_attr_temp1_crit);
device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst); device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
...@@ -370,6 +378,8 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -370,6 +378,8 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -385,15 +395,18 @@ static int lm92_attach_adapter(struct i2c_adapter *adapter) ...@@ -385,15 +395,18 @@ static int lm92_attach_adapter(struct i2c_adapter *adapter)
static int lm92_detach_client(struct i2c_client *client) static int lm92_detach_client(struct i2c_client *client)
{ {
struct lm92_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -32,7 +32,8 @@ ...@@ -32,7 +32,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
0x29, 0x2a, 0x2b, 0x29, 0x2a, 0x2b,
...@@ -104,6 +105,7 @@ static struct i2c_driver max1619_driver = { ...@@ -104,6 +105,7 @@ static struct i2c_driver max1619_driver = {
struct max1619_data { struct max1619_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -275,6 +277,12 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -275,6 +277,12 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
max1619_init_client(new_client); max1619_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp2_input); device_create_file(&new_client->dev, &dev_attr_temp2_input);
device_create_file(&new_client->dev, &dev_attr_temp2_min); device_create_file(&new_client->dev, &dev_attr_temp2_min);
...@@ -285,6 +293,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -285,6 +293,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -308,15 +318,18 @@ static void max1619_init_client(struct i2c_client *client) ...@@ -308,15 +318,18 @@ static void max1619_init_client(struct i2c_client *client)
static int max1619_detach_client(struct i2c_client *client) static int max1619_detach_client(struct i2c_client *client)
{ {
struct max1619_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
static unsigned short normal_i2c[] = { I2C_CLIENT_END }; static unsigned short normal_i2c[] = { I2C_CLIENT_END };
...@@ -186,6 +188,7 @@ static inline u8 PWM_TO_REG(int val, int inv) ...@@ -186,6 +188,7 @@ static inline u8 PWM_TO_REG(int val, int inv)
struct pc87360_data { struct pc87360_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
...@@ -838,6 +841,12 @@ int pc87360_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -838,6 +841,12 @@ int pc87360_detect(struct i2c_adapter *adapter, int address, int kind)
} }
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
if (data->innr) { if (data->innr) {
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
...@@ -974,6 +983,8 @@ int pc87360_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -974,6 +983,8 @@ int pc87360_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR3:
i2c_detach_client(new_client);
ERROR2: ERROR2:
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (data->address[i]) { if (data->address[i]) {
...@@ -990,6 +1001,8 @@ static int pc87360_detach_client(struct i2c_client *client) ...@@ -990,6 +1001,8 @@ static int pc87360_detach_client(struct i2c_client *client)
struct pc87360_data *data = i2c_get_clientdata(client); struct pc87360_data *data = i2c_get_clientdata(client);
int i; int i;
hwmon_device_unregister(data->class_dev);
if ((i = i2c_detach_client(client))) { if ((i = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
......
...@@ -56,6 +56,8 @@ ...@@ -56,6 +56,8 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -168,6 +170,7 @@ static inline u8 DIV_TO_REG(int val) ...@@ -168,6 +170,7 @@ static inline u8 DIV_TO_REG(int val)
allocated. */ allocated. */
struct sis5595_data { struct sis5595_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -578,6 +581,12 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -578,6 +581,12 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
} }
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in0_min); device_create_file(&new_client->dev, &dev_attr_in0_min);
device_create_file(&new_client->dev, &dev_attr_in0_max); device_create_file(&new_client->dev, &dev_attr_in0_max);
...@@ -608,7 +617,9 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -608,7 +617,9 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
} }
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit_release: exit_release:
...@@ -619,8 +630,11 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -619,8 +630,11 @@ int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
static int sis5595_detach_client(struct i2c_client *client) static int sis5595_detach_client(struct i2c_client *client)
{ {
struct sis5595_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); "Client deregistration failed, client not detached.\n");
...@@ -630,7 +644,7 @@ static int sis5595_detach_client(struct i2c_client *client) ...@@ -630,7 +644,7 @@ static int sis5595_detach_client(struct i2c_client *client)
if (i2c_is_isa_client(client)) if (i2c_is_isa_client(client))
release_region(client->addr, SIS5595_EXTENT); release_region(client->addr, SIS5595_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -100,6 +102,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80}; ...@@ -100,6 +102,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80};
struct smsc47b397_data { struct smsc47b397_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -226,8 +229,11 @@ static int smsc47b397_attach_adapter(struct i2c_adapter *adapter) ...@@ -226,8 +229,11 @@ static int smsc47b397_attach_adapter(struct i2c_adapter *adapter)
static int smsc47b397_detach_client(struct i2c_client *client) static int smsc47b397_detach_client(struct i2c_client *client)
{ {
struct smsc47b397_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
...@@ -235,7 +241,7 @@ static int smsc47b397_detach_client(struct i2c_client *client) ...@@ -235,7 +241,7 @@ static int smsc47b397_detach_client(struct i2c_client *client)
} }
release_region(client->addr, SMSC_EXTENT); release_region(client->addr, SMSC_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
...@@ -285,6 +291,12 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) ...@@ -285,6 +291,12 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto error_free; 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, 1);
device_create_file_temp(new_client, 2); device_create_file_temp(new_client, 2);
device_create_file_temp(new_client, 3); device_create_file_temp(new_client, 3);
...@@ -297,6 +309,8 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) ...@@ -297,6 +309,8 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
return 0; return 0;
error_detach:
i2c_detach_client(new_client);
error_free: error_free:
kfree(data); kfree(data);
error_release: error_release:
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -108,6 +110,7 @@ superio_exit(void) ...@@ -108,6 +110,7 @@ superio_exit(void)
struct smsc47m1_data { struct smsc47m1_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -461,6 +464,13 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -461,6 +464,13 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
function. */ function. */
smsc47m1_update_device(&new_client->dev, 1); smsc47m1_update_device(&new_client->dev, 1);
/* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error_detach;
}
if (fan1) { if (fan1) {
device_create_file(&new_client->dev, &dev_attr_fan1_input); device_create_file(&new_client->dev, &dev_attr_fan1_input);
device_create_file(&new_client->dev, &dev_attr_fan1_min); device_create_file(&new_client->dev, &dev_attr_fan1_min);
...@@ -494,6 +504,8 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -494,6 +504,8 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
error_detach:
i2c_detach_client(new_client);
error_free: error_free:
kfree(data); kfree(data);
error_release: error_release:
...@@ -503,8 +515,11 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -503,8 +515,11 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
static int smsc47m1_detach_client(struct i2c_client *client) static int smsc47m1_detach_client(struct i2c_client *client)
{ {
struct smsc47m1_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
...@@ -512,7 +527,7 @@ static int smsc47m1_detach_client(struct i2c_client *client) ...@@ -512,7 +527,7 @@ static int smsc47m1_detach_client(struct i2c_client *client)
} }
release_region(client->addr, SMSC_EXTENT); release_region(client->addr, SMSC_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -297,6 +299,7 @@ static inline long TEMP_FROM_REG10(u16 val) ...@@ -297,6 +299,7 @@ static inline long TEMP_FROM_REG10(u16 val)
via686a client is allocated. */ via686a client is allocated. */
struct via686a_data { struct via686a_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */ char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
...@@ -637,7 +640,7 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -637,7 +640,7 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) { if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
err = -ENOMEM; err = -ENOMEM;
goto ERROR0; goto exit_release;
} }
memset(data, 0, sizeof(struct via686a_data)); memset(data, 0, sizeof(struct via686a_data));
...@@ -655,12 +658,18 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -655,12 +658,18 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
init_MUTEX(&data->update_lock); init_MUTEX(&data->update_lock);
/* Tell the I2C layer a new client has arrived */ /* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client))) if ((err = i2c_attach_client(new_client)))
goto ERROR3; goto exit_free;
/* Initialize the VIA686A chip */ /* Initialize the VIA686A chip */
via686a_init_client(new_client); via686a_init_client(new_client);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input); device_create_file(&new_client->dev, &dev_attr_in1_input);
device_create_file(&new_client->dev, &dev_attr_in2_input); device_create_file(&new_client->dev, &dev_attr_in2_input);
...@@ -695,17 +704,22 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -695,17 +704,22 @@ static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR3: exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data); kfree(data);
ERROR0: exit_release:
release_region(address, VIA686A_EXTENT); release_region(address, VIA686A_EXTENT);
return err; return err;
} }
static int via686a_detach_client(struct i2c_client *client) static int via686a_detach_client(struct i2c_client *client)
{ {
struct via686a_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); "Client deregistration failed, client not detached.\n");
...@@ -713,7 +727,7 @@ static int via686a_detach_client(struct i2c_client *client) ...@@ -713,7 +727,7 @@ static int via686a_detach_client(struct i2c_client *client)
} }
release_region(client->addr, VIA686A_EXTENT); release_region(client->addr, VIA686A_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
#include "lm75.h" #include "lm75.h"
...@@ -177,6 +179,7 @@ temp1_to_reg(int temp) ...@@ -177,6 +179,7 @@ temp1_to_reg(int temp)
struct w83627ehf_data { struct w83627ehf_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
struct semaphore update_lock; struct semaphore update_lock;
...@@ -723,6 +726,12 @@ static int w83627ehf_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -723,6 +726,12 @@ static int w83627ehf_detect(struct i2c_adapter *adapter, int address, int kind)
data->has_fan |= (1 << 4); data->has_fan |= (1 << 4);
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&client->dev, &dev_attr_fan1_input); device_create_file(&client->dev, &dev_attr_fan1_input);
device_create_file(&client->dev, &dev_attr_fan1_min); device_create_file(&client->dev, &dev_attr_fan1_min);
device_create_file(&client->dev, &dev_attr_fan1_div); device_create_file(&client->dev, &dev_attr_fan1_div);
...@@ -756,6 +765,8 @@ static int w83627ehf_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -756,6 +765,8 @@ static int w83627ehf_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
exit_detach:
i2c_detach_client(client);
exit_free: exit_free:
kfree(data); kfree(data);
exit_release: exit_release:
...@@ -773,15 +784,18 @@ static int w83627ehf_attach_adapter(struct i2c_adapter *adapter) ...@@ -773,15 +784,18 @@ static int w83627ehf_attach_adapter(struct i2c_adapter *adapter)
static int w83627ehf_detach_client(struct i2c_client *client) static int w83627ehf_detach_client(struct i2c_client *client)
{ {
struct w83627ehf_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
release_region(client->addr, REGION_LENGTH); release_region(client->addr, REGION_LENGTH);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
#include "lm75.h" #include "lm75.h"
...@@ -277,6 +279,7 @@ static inline u8 DIV_TO_REG(long val) ...@@ -277,6 +279,7 @@ static inline u8 DIV_TO_REG(long val)
dynamically allocated, at the same time when a new client is allocated. */ dynamically allocated, at the same time when a new client is allocated. */
struct w83627hf_data { struct w83627hf_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -1102,6 +1105,12 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address, ...@@ -1102,6 +1105,12 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3)); data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3));
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
if (kind != w83697hf) if (kind != w83697hf)
device_create_file_in(new_client, 1); device_create_file_in(new_client, 1);
...@@ -1152,6 +1161,8 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address, ...@@ -1152,6 +1161,8 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
return 0; return 0;
ERROR3:
i2c_detach_client(new_client);
ERROR2: ERROR2:
kfree(data); kfree(data);
ERROR1: ERROR1:
...@@ -1162,8 +1173,11 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address, ...@@ -1162,8 +1173,11 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
static int w83627hf_detach_client(struct i2c_client *client) static int w83627hf_detach_client(struct i2c_client *client)
{ {
struct w83627hf_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, dev_err(&client->dev,
"Client deregistration failed, client not detached.\n"); "Client deregistration failed, client not detached.\n");
...@@ -1171,7 +1185,7 @@ static int w83627hf_detach_client(struct i2c_client *client) ...@@ -1171,7 +1185,7 @@ static int w83627hf_detach_client(struct i2c_client *client)
} }
release_region(client->addr, WINB_EXTENT); release_region(client->addr, WINB_EXTENT);
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/i2c-vid.h> #include <linux/i2c-vid.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <asm/io.h> #include <asm/io.h>
#include "lm75.h" #include "lm75.h"
...@@ -218,6 +220,7 @@ DIV_TO_REG(long val, enum chips type) ...@@ -218,6 +220,7 @@ DIV_TO_REG(long val, enum chips type)
allocated. */ allocated. */
struct w83781d_data { struct w83781d_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock; struct semaphore lock;
enum chips type; enum chips type;
...@@ -961,10 +964,10 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, ...@@ -961,10 +964,10 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
ERROR_SC_3: ERROR_SC_3:
i2c_detach_client(data->lm75[0]); i2c_detach_client(data->lm75[0]);
ERROR_SC_2: ERROR_SC_2:
if (NULL != data->lm75[1]) if (data->lm75[1])
kfree(data->lm75[1]); kfree(data->lm75[1]);
ERROR_SC_1: ERROR_SC_1:
if (NULL != data->lm75[0]) if (data->lm75[0])
kfree(data->lm75[0]); kfree(data->lm75[0]);
ERROR_SC_0: ERROR_SC_0:
return err; return err;
...@@ -1189,6 +1192,12 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1189,6 +1192,12 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
data->pwmenable[i] = 1; data->pwmenable[i] = 1;
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR4;
}
device_create_file_in(new_client, 0); device_create_file_in(new_client, 0);
if (kind != w83783s) if (kind != w83783s)
device_create_file_in(new_client, 1); device_create_file_in(new_client, 1);
...@@ -1241,6 +1250,15 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1241,6 +1250,15 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
return 0; return 0;
ERROR4:
if (data->lm75[1]) {
i2c_detach_client(data->lm75[1]);
kfree(data->lm75[1]);
}
if (data->lm75[0]) {
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[0]);
}
ERROR3: ERROR3:
i2c_detach_client(new_client); i2c_detach_client(new_client);
ERROR2: ERROR2:
...@@ -1255,8 +1273,13 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -1255,8 +1273,13 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
static int static int
w83781d_detach_client(struct i2c_client *client) w83781d_detach_client(struct i2c_client *client)
{ {
struct w83781d_data *data = i2c_get_clientdata(client);
int err; int err;
/* main client */
if (data)
hwmon_device_unregister(data->class_dev);
if (i2c_is_isa_client(client)) if (i2c_is_isa_client(client))
release_region(client->addr, W83781D_EXTENT); release_region(client->addr, W83781D_EXTENT);
...@@ -1266,13 +1289,13 @@ w83781d_detach_client(struct i2c_client *client) ...@@ -1266,13 +1289,13 @@ w83781d_detach_client(struct i2c_client *client)
return err; return err;
} }
if (i2c_get_clientdata(client)==NULL) { /* main client */
/* subclients */ if (data)
kfree(data);
/* subclient */
else
kfree(client); kfree(client);
} else {
/* main client */
kfree(i2c_get_clientdata(client));
}
return 0; return 0;
} }
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-sensor.h> #include <linux/i2c-sensor.h>
#include <linux/hwmon.h>
#include <linux/err.h>
/* How many retries on register read error */ /* How many retries on register read error */
#define MAX_RETRIES 5 #define MAX_RETRIES 5
...@@ -105,6 +107,7 @@ static struct i2c_driver w83l785ts_driver = { ...@@ -105,6 +107,7 @@ static struct i2c_driver w83l785ts_driver = {
struct w83l785ts_data { struct w83l785ts_data {
struct i2c_client client; struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock; struct semaphore update_lock;
char valid; /* zero until following fields are valid */ char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -239,11 +242,19 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -239,11 +242,19 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
*/ */
/* Register sysfs hooks */ /* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&new_client->dev, &dev_attr_temp1_input); device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_max); device_create_file(&new_client->dev, &dev_attr_temp1_max);
return 0; return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -252,15 +263,18 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -252,15 +263,18 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
static int w83l785ts_detach_client(struct i2c_client *client) static int w83l785ts_detach_client(struct i2c_client *client)
{ {
struct w83l785ts_data *data = i2c_get_clientdata(client);
int err; int err;
hwmon_device_unregister(data->class_dev);
if ((err = i2c_detach_client(client))) { if ((err = i2c_detach_client(client))) {
dev_err(&client->dev, "Client deregistration failed, " dev_err(&client->dev, "Client deregistration failed, "
"client not detached.\n"); "client not detached.\n");
return err; return err;
} }
kfree(i2c_get_clientdata(client)); kfree(data);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册