diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:14 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:14 -0400 |
commit | a888420af07b9a26b6d518328baa913fb704e950 (patch) | |
tree | b8d88c4e6837c007752d034fdccd6c3bddf44afa | |
parent | b6aacdcefac8ed60e77930b6e74129da6478e20e (diff) |
hwmon: (lm87) Convert to a new-style i2c driver
The new-style lm87 driver implements the optional detect() callback
to cover the use cases of the legacy driver.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r-- | drivers/hwmon/lm87.c | 99 |
1 files changed, 46 insertions, 53 deletions
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c index e1c183f0aae0..21970f0d53a1 100644 --- a/drivers/hwmon/lm87.c +++ b/drivers/hwmon/lm87.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Philip Edelbrock <phil@netroedge.com> | 5 | * Philip Edelbrock <phil@netroedge.com> |
6 | * Stephen Rousset <stephen.rousset@rocketlogix.com> | 6 | * Stephen Rousset <stephen.rousset@rocketlogix.com> |
7 | * Dan Eaton <dan.eaton@rocketlogix.com> | 7 | * Dan Eaton <dan.eaton@rocketlogix.com> |
8 | * Copyright (C) 2004,2007 Jean Delvare <khali@linux-fr.org> | 8 | * Copyright (C) 2004-2008 Jean Delvare <khali@linux-fr.org> |
9 | * | 9 | * |
10 | * Original port to Linux 2.6 by Jeff Oliver. | 10 | * Original port to Linux 2.6 by Jeff Oliver. |
11 | * | 11 | * |
@@ -157,22 +157,35 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C }; | |||
157 | * Functions declaration | 157 | * Functions declaration |
158 | */ | 158 | */ |
159 | 159 | ||
160 | static int lm87_attach_adapter(struct i2c_adapter *adapter); | 160 | static int lm87_probe(struct i2c_client *client, |
161 | static int lm87_detect(struct i2c_adapter *adapter, int address, int kind); | 161 | const struct i2c_device_id *id); |
162 | static int lm87_detect(struct i2c_client *new_client, int kind, | ||
163 | struct i2c_board_info *info); | ||
162 | static void lm87_init_client(struct i2c_client *client); | 164 | static void lm87_init_client(struct i2c_client *client); |
163 | static int lm87_detach_client(struct i2c_client *client); | 165 | static int lm87_remove(struct i2c_client *client); |
164 | static struct lm87_data *lm87_update_device(struct device *dev); | 166 | static struct lm87_data *lm87_update_device(struct device *dev); |
165 | 167 | ||
166 | /* | 168 | /* |
167 | * Driver data (common to all clients) | 169 | * Driver data (common to all clients) |
168 | */ | 170 | */ |
169 | 171 | ||
172 | static const struct i2c_device_id lm87_id[] = { | ||
173 | { "lm87", lm87 }, | ||
174 | { "adm1024", adm1024 }, | ||
175 | { } | ||
176 | }; | ||
177 | MODULE_DEVICE_TABLE(i2c, lm87_id); | ||
178 | |||
170 | static struct i2c_driver lm87_driver = { | 179 | static struct i2c_driver lm87_driver = { |
180 | .class = I2C_CLASS_HWMON, | ||
171 | .driver = { | 181 | .driver = { |
172 | .name = "lm87", | 182 | .name = "lm87", |
173 | }, | 183 | }, |
174 | .attach_adapter = lm87_attach_adapter, | 184 | .probe = lm87_probe, |
175 | .detach_client = lm87_detach_client, | 185 | .remove = lm87_remove, |
186 | .id_table = lm87_id, | ||
187 | .detect = lm87_detect, | ||
188 | .address_data = &addr_data, | ||
176 | }; | 189 | }; |
177 | 190 | ||
178 | /* | 191 | /* |
@@ -180,7 +193,6 @@ static struct i2c_driver lm87_driver = { | |||
180 | */ | 193 | */ |
181 | 194 | ||
182 | struct lm87_data { | 195 | struct lm87_data { |
183 | struct i2c_client client; | ||
184 | struct device *hwmon_dev; | 196 | struct device *hwmon_dev; |
185 | struct mutex update_lock; | 197 | struct mutex update_lock; |
186 | char valid; /* zero until following fields are valid */ | 198 | char valid; /* zero until following fields are valid */ |
@@ -562,13 +574,6 @@ static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15); | |||
562 | * Real code | 574 | * Real code |
563 | */ | 575 | */ |
564 | 576 | ||
565 | static int lm87_attach_adapter(struct i2c_adapter *adapter) | ||
566 | { | ||
567 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
568 | return 0; | ||
569 | return i2c_probe(adapter, &addr_data, lm87_detect); | ||
570 | } | ||
571 | |||
572 | static struct attribute *lm87_attributes[] = { | 577 | static struct attribute *lm87_attributes[] = { |
573 | &dev_attr_in1_input.attr, | 578 | &dev_attr_in1_input.attr, |
574 | &dev_attr_in1_min.attr, | 579 | &dev_attr_in1_min.attr, |
@@ -656,33 +661,15 @@ static const struct attribute_group lm87_group_opt = { | |||
656 | .attrs = lm87_attributes_opt, | 661 | .attrs = lm87_attributes_opt, |
657 | }; | 662 | }; |
658 | 663 | ||
659 | /* | 664 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
660 | * The following function does more than just detection. If detection | 665 | static int lm87_detect(struct i2c_client *new_client, int kind, |
661 | * succeeds, it also registers the new chip. | 666 | struct i2c_board_info *info) |
662 | */ | ||
663 | static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | ||
664 | { | 667 | { |
665 | struct i2c_client *new_client; | 668 | struct i2c_adapter *adapter = new_client->adapter; |
666 | struct lm87_data *data; | ||
667 | int err = 0; | ||
668 | static const char *names[] = { "lm87", "adm1024" }; | 669 | static const char *names[] = { "lm87", "adm1024" }; |
669 | 670 | ||
670 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 671 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
671 | goto exit; | 672 | return -ENODEV; |
672 | |||
673 | if (!(data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL))) { | ||
674 | err = -ENOMEM; | ||
675 | goto exit; | ||
676 | } | ||
677 | |||
678 | /* The common I2C client data is placed right before the | ||
679 | LM87-specific data. */ | ||
680 | new_client = &data->client; | ||
681 | i2c_set_clientdata(new_client, data); | ||
682 | new_client->addr = address; | ||
683 | new_client->adapter = adapter; | ||
684 | new_client->driver = &lm87_driver; | ||
685 | new_client->flags = 0; | ||
686 | 673 | ||
687 | /* Default to an LM87 if forced */ | 674 | /* Default to an LM87 if forced */ |
688 | if (kind == 0) | 675 | if (kind == 0) |
@@ -704,20 +691,32 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
704 | || (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)) { | 691 | || (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)) { |
705 | dev_dbg(&adapter->dev, | 692 | dev_dbg(&adapter->dev, |
706 | "LM87 detection failed at 0x%02x.\n", | 693 | "LM87 detection failed at 0x%02x.\n", |
707 | address); | 694 | new_client->addr); |
708 | goto exit_free; | 695 | return -ENODEV; |
709 | } | 696 | } |
710 | } | 697 | } |
711 | 698 | ||
712 | /* We can fill in the remaining client fields */ | 699 | strlcpy(info->type, names[kind - 1], I2C_NAME_SIZE); |
713 | strlcpy(new_client->name, names[kind - 1], I2C_NAME_SIZE); | 700 | |
701 | return 0; | ||
702 | } | ||
703 | |||
704 | static int lm87_probe(struct i2c_client *new_client, | ||
705 | const struct i2c_device_id *id) | ||
706 | { | ||
707 | struct lm87_data *data; | ||
708 | int err; | ||
709 | |||
710 | data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL); | ||
711 | if (!data) { | ||
712 | err = -ENOMEM; | ||
713 | goto exit; | ||
714 | } | ||
715 | |||
716 | i2c_set_clientdata(new_client, data); | ||
714 | data->valid = 0; | 717 | data->valid = 0; |
715 | mutex_init(&data->update_lock); | 718 | mutex_init(&data->update_lock); |
716 | 719 | ||
717 | /* Tell the I2C layer a new client has arrived */ | ||
718 | if ((err = i2c_attach_client(new_client))) | ||
719 | goto exit_free; | ||
720 | |||
721 | /* Initialize the LM87 chip */ | 720 | /* Initialize the LM87 chip */ |
722 | lm87_init_client(new_client); | 721 | lm87_init_client(new_client); |
723 | 722 | ||
@@ -732,7 +731,7 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
732 | 731 | ||
733 | /* Register sysfs hooks */ | 732 | /* Register sysfs hooks */ |
734 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group))) | 733 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group))) |
735 | goto exit_detach; | 734 | goto exit_free; |
736 | 735 | ||
737 | if (data->channel & CHAN_NO_FAN(0)) { | 736 | if (data->channel & CHAN_NO_FAN(0)) { |
738 | if ((err = device_create_file(&new_client->dev, | 737 | if ((err = device_create_file(&new_client->dev, |
@@ -832,8 +831,6 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
832 | exit_remove: | 831 | exit_remove: |
833 | sysfs_remove_group(&new_client->dev.kobj, &lm87_group); | 832 | sysfs_remove_group(&new_client->dev.kobj, &lm87_group); |
834 | sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt); | 833 | sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt); |
835 | exit_detach: | ||
836 | i2c_detach_client(new_client); | ||
837 | exit_free: | 834 | exit_free: |
838 | kfree(data); | 835 | kfree(data); |
839 | exit: | 836 | exit: |
@@ -877,18 +874,14 @@ static void lm87_init_client(struct i2c_client *client) | |||
877 | } | 874 | } |
878 | } | 875 | } |
879 | 876 | ||
880 | static int lm87_detach_client(struct i2c_client *client) | 877 | static int lm87_remove(struct i2c_client *client) |
881 | { | 878 | { |
882 | struct lm87_data *data = i2c_get_clientdata(client); | 879 | struct lm87_data *data = i2c_get_clientdata(client); |
883 | int err; | ||
884 | 880 | ||
885 | hwmon_device_unregister(data->hwmon_dev); | 881 | hwmon_device_unregister(data->hwmon_dev); |
886 | sysfs_remove_group(&client->dev.kobj, &lm87_group); | 882 | sysfs_remove_group(&client->dev.kobj, &lm87_group); |
887 | sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); | 883 | sysfs_remove_group(&client->dev.kobj, &lm87_group_opt); |
888 | 884 | ||
889 | if ((err = i2c_detach_client(client))) | ||
890 | return err; | ||
891 | |||
892 | kfree(data); | 885 | kfree(data); |
893 | return 0; | 886 | return 0; |
894 | } | 887 | } |