diff options
author | Axel Lin <axel.lin@ingics.com> | 2014-07-03 09:59:49 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2014-08-04 10:01:37 -0400 |
commit | 4341fc3f32b278d136179772338ccaa31f222c99 (patch) | |
tree | 066177fd4444e84290e3ef8cb4cc336e1d58da4e /drivers/hwmon | |
parent | b060f3c4ac99b050b990b316637f7fd9898b9fd7 (diff) |
hwmon: (adm9240) Avoid forward declaration
Reorder functions to avoid forward declaration.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/adm9240.c | 315 |
1 files changed, 153 insertions, 162 deletions
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 086d02a9ecdc..8235ae4cbeb5 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -130,35 +130,6 @@ static inline unsigned int AOUT_FROM_REG(u8 reg) | |||
130 | return SCALE(reg, 1250, 255); | 130 | return SCALE(reg, 1250, 255); |
131 | } | 131 | } |
132 | 132 | ||
133 | static int adm9240_probe(struct i2c_client *client, | ||
134 | const struct i2c_device_id *id); | ||
135 | static int adm9240_detect(struct i2c_client *client, | ||
136 | struct i2c_board_info *info); | ||
137 | static void adm9240_init_client(struct i2c_client *client); | ||
138 | static int adm9240_remove(struct i2c_client *client); | ||
139 | static struct adm9240_data *adm9240_update_device(struct device *dev); | ||
140 | |||
141 | /* driver data */ | ||
142 | static const struct i2c_device_id adm9240_id[] = { | ||
143 | { "adm9240", adm9240 }, | ||
144 | { "ds1780", ds1780 }, | ||
145 | { "lm81", lm81 }, | ||
146 | { } | ||
147 | }; | ||
148 | MODULE_DEVICE_TABLE(i2c, adm9240_id); | ||
149 | |||
150 | static struct i2c_driver adm9240_driver = { | ||
151 | .class = I2C_CLASS_HWMON, | ||
152 | .driver = { | ||
153 | .name = "adm9240", | ||
154 | }, | ||
155 | .probe = adm9240_probe, | ||
156 | .remove = adm9240_remove, | ||
157 | .id_table = adm9240_id, | ||
158 | .detect = adm9240_detect, | ||
159 | .address_list = normal_i2c, | ||
160 | }; | ||
161 | |||
162 | /* per client data */ | 133 | /* per client data */ |
163 | struct adm9240_data { | 134 | struct adm9240_data { |
164 | struct device *hwmon_dev; | 135 | struct device *hwmon_dev; |
@@ -181,6 +152,110 @@ struct adm9240_data { | |||
181 | u8 vrm; /* -- vrm set on startup, no accessor */ | 152 | u8 vrm; /* -- vrm set on startup, no accessor */ |
182 | }; | 153 | }; |
183 | 154 | ||
155 | /* write new fan div, callers must hold data->update_lock */ | ||
156 | static void adm9240_write_fan_div(struct i2c_client *client, int nr, | ||
157 | u8 fan_div) | ||
158 | { | ||
159 | u8 reg, old, shift = (nr + 2) * 2; | ||
160 | |||
161 | reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); | ||
162 | old = (reg >> shift) & 3; | ||
163 | reg &= ~(3 << shift); | ||
164 | reg |= (fan_div << shift); | ||
165 | i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg); | ||
166 | dev_dbg(&client->dev, | ||
167 | "fan%d clock divider changed from %u to %u\n", | ||
168 | nr + 1, 1 << old, 1 << fan_div); | ||
169 | } | ||
170 | |||
171 | static struct adm9240_data *adm9240_update_device(struct device *dev) | ||
172 | { | ||
173 | struct i2c_client *client = to_i2c_client(dev); | ||
174 | struct adm9240_data *data = i2c_get_clientdata(client); | ||
175 | int i; | ||
176 | |||
177 | mutex_lock(&data->update_lock); | ||
178 | |||
179 | /* minimum measurement cycle: 1.75 seconds */ | ||
180 | if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4)) | ||
181 | || !data->valid) { | ||
182 | |||
183 | for (i = 0; i < 6; i++) { /* read voltages */ | ||
184 | data->in[i] = i2c_smbus_read_byte_data(client, | ||
185 | ADM9240_REG_IN(i)); | ||
186 | } | ||
187 | data->alarms = i2c_smbus_read_byte_data(client, | ||
188 | ADM9240_REG_INT(0)) | | ||
189 | i2c_smbus_read_byte_data(client, | ||
190 | ADM9240_REG_INT(1)) << 8; | ||
191 | |||
192 | /* | ||
193 | * read temperature: assume temperature changes less than | ||
194 | * 0.5'C per two measurement cycles thus ignore possible | ||
195 | * but unlikely aliasing error on lsb reading. --Grant | ||
196 | */ | ||
197 | data->temp = ((i2c_smbus_read_byte_data(client, | ||
198 | ADM9240_REG_TEMP) << 8) | | ||
199 | i2c_smbus_read_byte_data(client, | ||
200 | ADM9240_REG_TEMP_CONF)) / 128; | ||
201 | |||
202 | for (i = 0; i < 2; i++) { /* read fans */ | ||
203 | data->fan[i] = i2c_smbus_read_byte_data(client, | ||
204 | ADM9240_REG_FAN(i)); | ||
205 | |||
206 | /* adjust fan clock divider on overflow */ | ||
207 | if (data->valid && data->fan[i] == 255 && | ||
208 | data->fan_div[i] < 3) { | ||
209 | |||
210 | adm9240_write_fan_div(client, i, | ||
211 | ++data->fan_div[i]); | ||
212 | |||
213 | /* adjust fan_min if active, but not to 0 */ | ||
214 | if (data->fan_min[i] < 255 && | ||
215 | data->fan_min[i] >= 2) | ||
216 | data->fan_min[i] /= 2; | ||
217 | } | ||
218 | } | ||
219 | data->last_updated_measure = jiffies; | ||
220 | } | ||
221 | |||
222 | /* minimum config reading cycle: 300 seconds */ | ||
223 | if (time_after(jiffies, data->last_updated_config + (HZ * 300)) | ||
224 | || !data->valid) { | ||
225 | |||
226 | for (i = 0; i < 6; i++) { | ||
227 | data->in_min[i] = i2c_smbus_read_byte_data(client, | ||
228 | ADM9240_REG_IN_MIN(i)); | ||
229 | data->in_max[i] = i2c_smbus_read_byte_data(client, | ||
230 | ADM9240_REG_IN_MAX(i)); | ||
231 | } | ||
232 | for (i = 0; i < 2; i++) { | ||
233 | data->fan_min[i] = i2c_smbus_read_byte_data(client, | ||
234 | ADM9240_REG_FAN_MIN(i)); | ||
235 | } | ||
236 | data->temp_max[0] = i2c_smbus_read_byte_data(client, | ||
237 | ADM9240_REG_TEMP_MAX(0)); | ||
238 | data->temp_max[1] = i2c_smbus_read_byte_data(client, | ||
239 | ADM9240_REG_TEMP_MAX(1)); | ||
240 | |||
241 | /* read fan divs and 5-bit VID */ | ||
242 | i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); | ||
243 | data->fan_div[0] = (i >> 4) & 3; | ||
244 | data->fan_div[1] = (i >> 6) & 3; | ||
245 | data->vid = i & 0x0f; | ||
246 | data->vid |= (i2c_smbus_read_byte_data(client, | ||
247 | ADM9240_REG_VID4) & 1) << 4; | ||
248 | /* read analog out */ | ||
249 | data->aout = i2c_smbus_read_byte_data(client, | ||
250 | ADM9240_REG_ANALOG_OUT); | ||
251 | |||
252 | data->last_updated_config = jiffies; | ||
253 | data->valid = 1; | ||
254 | } | ||
255 | mutex_unlock(&data->update_lock); | ||
256 | return data; | ||
257 | } | ||
258 | |||
184 | /*** sysfs accessors ***/ | 259 | /*** sysfs accessors ***/ |
185 | 260 | ||
186 | /* temperature */ | 261 | /* temperature */ |
@@ -340,22 +415,6 @@ static ssize_t show_fan_div(struct device *dev, | |||
340 | return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]); | 415 | return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]); |
341 | } | 416 | } |
342 | 417 | ||
343 | /* write new fan div, callers must hold data->update_lock */ | ||
344 | static void adm9240_write_fan_div(struct i2c_client *client, int nr, | ||
345 | u8 fan_div) | ||
346 | { | ||
347 | u8 reg, old, shift = (nr + 2) * 2; | ||
348 | |||
349 | reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); | ||
350 | old = (reg >> shift) & 3; | ||
351 | reg &= ~(3 << shift); | ||
352 | reg |= (fan_div << shift); | ||
353 | i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg); | ||
354 | dev_dbg(&client->dev, | ||
355 | "fan%d clock divider changed from %u to %u\n", | ||
356 | nr + 1, 1 << old, 1 << fan_div); | ||
357 | } | ||
358 | |||
359 | /* | 418 | /* |
360 | * set fan speed low limit: | 419 | * set fan speed low limit: |
361 | * | 420 | * |
@@ -620,49 +679,6 @@ static int adm9240_detect(struct i2c_client *new_client, | |||
620 | return 0; | 679 | return 0; |
621 | } | 680 | } |
622 | 681 | ||
623 | static int adm9240_probe(struct i2c_client *new_client, | ||
624 | const struct i2c_device_id *id) | ||
625 | { | ||
626 | struct adm9240_data *data; | ||
627 | int err; | ||
628 | |||
629 | data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL); | ||
630 | if (!data) | ||
631 | return -ENOMEM; | ||
632 | |||
633 | i2c_set_clientdata(new_client, data); | ||
634 | mutex_init(&data->update_lock); | ||
635 | |||
636 | adm9240_init_client(new_client); | ||
637 | |||
638 | /* populate sysfs filesystem */ | ||
639 | err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group); | ||
640 | if (err) | ||
641 | return err; | ||
642 | |||
643 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
644 | if (IS_ERR(data->hwmon_dev)) { | ||
645 | err = PTR_ERR(data->hwmon_dev); | ||
646 | goto exit_remove; | ||
647 | } | ||
648 | |||
649 | return 0; | ||
650 | |||
651 | exit_remove: | ||
652 | sysfs_remove_group(&new_client->dev.kobj, &adm9240_group); | ||
653 | return err; | ||
654 | } | ||
655 | |||
656 | static int adm9240_remove(struct i2c_client *client) | ||
657 | { | ||
658 | struct adm9240_data *data = i2c_get_clientdata(client); | ||
659 | |||
660 | hwmon_device_unregister(data->hwmon_dev); | ||
661 | sysfs_remove_group(&client->dev.kobj, &adm9240_group); | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static void adm9240_init_client(struct i2c_client *client) | 682 | static void adm9240_init_client(struct i2c_client *client) |
667 | { | 683 | { |
668 | struct adm9240_data *data = i2c_get_clientdata(client); | 684 | struct adm9240_data *data = i2c_get_clientdata(client); |
@@ -705,93 +721,68 @@ static void adm9240_init_client(struct i2c_client *client) | |||
705 | } | 721 | } |
706 | } | 722 | } |
707 | 723 | ||
708 | static struct adm9240_data *adm9240_update_device(struct device *dev) | 724 | static int adm9240_probe(struct i2c_client *new_client, |
725 | const struct i2c_device_id *id) | ||
709 | { | 726 | { |
710 | struct i2c_client *client = to_i2c_client(dev); | 727 | struct adm9240_data *data; |
711 | struct adm9240_data *data = i2c_get_clientdata(client); | 728 | int err; |
712 | int i; | ||
713 | 729 | ||
714 | mutex_lock(&data->update_lock); | 730 | data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL); |
731 | if (!data) | ||
732 | return -ENOMEM; | ||
715 | 733 | ||
716 | /* minimum measurement cycle: 1.75 seconds */ | 734 | i2c_set_clientdata(new_client, data); |
717 | if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4)) | 735 | mutex_init(&data->update_lock); |
718 | || !data->valid) { | ||
719 | 736 | ||
720 | for (i = 0; i < 6; i++) { /* read voltages */ | 737 | adm9240_init_client(new_client); |
721 | data->in[i] = i2c_smbus_read_byte_data(client, | ||
722 | ADM9240_REG_IN(i)); | ||
723 | } | ||
724 | data->alarms = i2c_smbus_read_byte_data(client, | ||
725 | ADM9240_REG_INT(0)) | | ||
726 | i2c_smbus_read_byte_data(client, | ||
727 | ADM9240_REG_INT(1)) << 8; | ||
728 | 738 | ||
729 | /* | 739 | /* populate sysfs filesystem */ |
730 | * read temperature: assume temperature changes less than | 740 | err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group); |
731 | * 0.5'C per two measurement cycles thus ignore possible | 741 | if (err) |
732 | * but unlikely aliasing error on lsb reading. --Grant | 742 | return err; |
733 | */ | ||
734 | data->temp = ((i2c_smbus_read_byte_data(client, | ||
735 | ADM9240_REG_TEMP) << 8) | | ||
736 | i2c_smbus_read_byte_data(client, | ||
737 | ADM9240_REG_TEMP_CONF)) / 128; | ||
738 | 743 | ||
739 | for (i = 0; i < 2; i++) { /* read fans */ | 744 | data->hwmon_dev = hwmon_device_register(&new_client->dev); |
740 | data->fan[i] = i2c_smbus_read_byte_data(client, | 745 | if (IS_ERR(data->hwmon_dev)) { |
741 | ADM9240_REG_FAN(i)); | 746 | err = PTR_ERR(data->hwmon_dev); |
747 | goto exit_remove; | ||
748 | } | ||
742 | 749 | ||
743 | /* adjust fan clock divider on overflow */ | 750 | return 0; |
744 | if (data->valid && data->fan[i] == 255 && | ||
745 | data->fan_div[i] < 3) { | ||
746 | 751 | ||
747 | adm9240_write_fan_div(client, i, | 752 | exit_remove: |
748 | ++data->fan_div[i]); | 753 | sysfs_remove_group(&new_client->dev.kobj, &adm9240_group); |
754 | return err; | ||
755 | } | ||
749 | 756 | ||
750 | /* adjust fan_min if active, but not to 0 */ | 757 | static int adm9240_remove(struct i2c_client *client) |
751 | if (data->fan_min[i] < 255 && | 758 | { |
752 | data->fan_min[i] >= 2) | 759 | struct adm9240_data *data = i2c_get_clientdata(client); |
753 | data->fan_min[i] /= 2; | ||
754 | } | ||
755 | } | ||
756 | data->last_updated_measure = jiffies; | ||
757 | } | ||
758 | 760 | ||
759 | /* minimum config reading cycle: 300 seconds */ | 761 | hwmon_device_unregister(data->hwmon_dev); |
760 | if (time_after(jiffies, data->last_updated_config + (HZ * 300)) | 762 | sysfs_remove_group(&client->dev.kobj, &adm9240_group); |
761 | || !data->valid) { | ||
762 | 763 | ||
763 | for (i = 0; i < 6; i++) { | 764 | return 0; |
764 | data->in_min[i] = i2c_smbus_read_byte_data(client, | 765 | } |
765 | ADM9240_REG_IN_MIN(i)); | ||
766 | data->in_max[i] = i2c_smbus_read_byte_data(client, | ||
767 | ADM9240_REG_IN_MAX(i)); | ||
768 | } | ||
769 | for (i = 0; i < 2; i++) { | ||
770 | data->fan_min[i] = i2c_smbus_read_byte_data(client, | ||
771 | ADM9240_REG_FAN_MIN(i)); | ||
772 | } | ||
773 | data->temp_max[0] = i2c_smbus_read_byte_data(client, | ||
774 | ADM9240_REG_TEMP_MAX(0)); | ||
775 | data->temp_max[1] = i2c_smbus_read_byte_data(client, | ||
776 | ADM9240_REG_TEMP_MAX(1)); | ||
777 | 766 | ||
778 | /* read fan divs and 5-bit VID */ | 767 | static const struct i2c_device_id adm9240_id[] = { |
779 | i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); | 768 | { "adm9240", adm9240 }, |
780 | data->fan_div[0] = (i >> 4) & 3; | 769 | { "ds1780", ds1780 }, |
781 | data->fan_div[1] = (i >> 6) & 3; | 770 | { "lm81", lm81 }, |
782 | data->vid = i & 0x0f; | 771 | { } |
783 | data->vid |= (i2c_smbus_read_byte_data(client, | 772 | }; |
784 | ADM9240_REG_VID4) & 1) << 4; | 773 | MODULE_DEVICE_TABLE(i2c, adm9240_id); |
785 | /* read analog out */ | ||
786 | data->aout = i2c_smbus_read_byte_data(client, | ||
787 | ADM9240_REG_ANALOG_OUT); | ||
788 | 774 | ||
789 | data->last_updated_config = jiffies; | 775 | static struct i2c_driver adm9240_driver = { |
790 | data->valid = 1; | 776 | .class = I2C_CLASS_HWMON, |
791 | } | 777 | .driver = { |
792 | mutex_unlock(&data->update_lock); | 778 | .name = "adm9240", |
793 | return data; | 779 | }, |
794 | } | 780 | .probe = adm9240_probe, |
781 | .remove = adm9240_remove, | ||
782 | .id_table = adm9240_id, | ||
783 | .detect = adm9240_detect, | ||
784 | .address_list = normal_i2c, | ||
785 | }; | ||
795 | 786 | ||
796 | module_i2c_driver(adm9240_driver); | 787 | module_i2c_driver(adm9240_driver); |
797 | 788 | ||