diff options
Diffstat (limited to 'drivers/hwmon/gl518sm.c')
-rw-r--r-- | drivers/hwmon/gl518sm.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 6bedf729dcf5..49972929a69b 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c | |||
@@ -42,6 +42,8 @@ | |||
42 | #include <linux/jiffies.h> | 42 | #include <linux/jiffies.h> |
43 | #include <linux/i2c.h> | 43 | #include <linux/i2c.h> |
44 | #include <linux/i2c-sensor.h> | 44 | #include <linux/i2c-sensor.h> |
45 | #include <linux/hwmon.h> | ||
46 | #include <linux/err.h> | ||
45 | 47 | ||
46 | /* Addresses to scan */ | 48 | /* Addresses to scan */ |
47 | static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; | 49 | 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 | /* Each client has this additional data */ | 119 | /* Each client has this additional data */ |
118 | struct gl518_data { | 120 | struct gl518_data { |
119 | struct i2c_client client; | 121 | struct i2c_client client; |
122 | struct class_device *class_dev; | ||
120 | enum chips type; | 123 | enum chips type; |
121 | 124 | ||
122 | struct semaphore update_lock; | 125 | struct semaphore update_lock; |
@@ -419,6 +422,12 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind) | |||
419 | gl518_init_client((struct i2c_client *) new_client); | 422 | gl518_init_client((struct i2c_client *) new_client); |
420 | 423 | ||
421 | /* Register sysfs hooks */ | 424 | /* Register sysfs hooks */ |
425 | data->class_dev = hwmon_device_register(&new_client->dev); | ||
426 | if (IS_ERR(data->class_dev)) { | ||
427 | err = PTR_ERR(data->class_dev); | ||
428 | goto exit_detach; | ||
429 | } | ||
430 | |||
422 | device_create_file(&new_client->dev, &dev_attr_in0_input); | 431 | device_create_file(&new_client->dev, &dev_attr_in0_input); |
423 | device_create_file(&new_client->dev, &dev_attr_in1_input); | 432 | device_create_file(&new_client->dev, &dev_attr_in1_input); |
424 | device_create_file(&new_client->dev, &dev_attr_in2_input); | 433 | 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 | /* OK, this is not exactly good programming practice, usually. But it is | 459 | /* OK, this is not exactly good programming practice, usually. But it is |
451 | very code-efficient in this case. */ | 460 | very code-efficient in this case. */ |
452 | 461 | ||
462 | exit_detach: | ||
463 | i2c_detach_client(new_client); | ||
453 | exit_free: | 464 | exit_free: |
454 | kfree(data); | 465 | kfree(data); |
455 | exit: | 466 | exit: |
@@ -477,16 +488,18 @@ static void gl518_init_client(struct i2c_client *client) | |||
477 | 488 | ||
478 | static int gl518_detach_client(struct i2c_client *client) | 489 | static int gl518_detach_client(struct i2c_client *client) |
479 | { | 490 | { |
491 | struct gl518_data *data = i2c_get_clientdata(client); | ||
480 | int err; | 492 | int err; |
481 | 493 | ||
494 | hwmon_device_unregister(data->class_dev); | ||
495 | |||
482 | if ((err = i2c_detach_client(client))) { | 496 | if ((err = i2c_detach_client(client))) { |
483 | dev_err(&client->dev, "Client deregistration failed, " | 497 | dev_err(&client->dev, "Client deregistration failed, " |
484 | "client not detached.\n"); | 498 | "client not detached.\n"); |
485 | return err; | 499 | return err; |
486 | } | 500 | } |
487 | 501 | ||
488 | kfree(i2c_get_clientdata(client)); | 502 | kfree(data); |
489 | |||
490 | return 0; | 503 | return 0; |
491 | } | 504 | } |
492 | 505 | ||