diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/smsc47m1.c | 115 |
1 files changed, 55 insertions, 60 deletions
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 23a22c4eee51..d7485659acc5 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -142,11 +142,6 @@ struct smsc47m1_sio_data { | |||
142 | u8 activate; /* Remember initial device state */ | 142 | u8 activate; /* Remember initial device state */ |
143 | }; | 143 | }; |
144 | 144 | ||
145 | |||
146 | static int __exit smsc47m1_remove(struct platform_device *pdev); | ||
147 | static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, | ||
148 | int init); | ||
149 | |||
150 | static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg) | 145 | static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg) |
151 | { | 146 | { |
152 | return inb_p(data->addr + reg); | 147 | return inb_p(data->addr + reg); |
@@ -158,13 +153,54 @@ static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg, | |||
158 | outb_p(value, data->addr + reg); | 153 | outb_p(value, data->addr + reg); |
159 | } | 154 | } |
160 | 155 | ||
161 | static struct platform_driver smsc47m1_driver = { | 156 | static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, |
162 | .driver = { | 157 | int init) |
163 | .owner = THIS_MODULE, | 158 | { |
164 | .name = DRVNAME, | 159 | struct smsc47m1_data *data = dev_get_drvdata(dev); |
165 | }, | 160 | |
166 | .remove = __exit_p(smsc47m1_remove), | 161 | mutex_lock(&data->update_lock); |
167 | }; | 162 | |
163 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) { | ||
164 | int i, fan_nr; | ||
165 | fan_nr = data->type == smsc47m2 ? 3 : 2; | ||
166 | |||
167 | for (i = 0; i < fan_nr; i++) { | ||
168 | data->fan[i] = smsc47m1_read_value(data, | ||
169 | SMSC47M1_REG_FAN[i]); | ||
170 | data->fan_preload[i] = smsc47m1_read_value(data, | ||
171 | SMSC47M1_REG_FAN_PRELOAD[i]); | ||
172 | data->pwm[i] = smsc47m1_read_value(data, | ||
173 | SMSC47M1_REG_PWM[i]); | ||
174 | } | ||
175 | |||
176 | i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV); | ||
177 | data->fan_div[0] = (i >> 4) & 0x03; | ||
178 | data->fan_div[1] = i >> 6; | ||
179 | |||
180 | data->alarms = smsc47m1_read_value(data, | ||
181 | SMSC47M1_REG_ALARM) >> 6; | ||
182 | /* Clear alarms if needed */ | ||
183 | if (data->alarms) | ||
184 | smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0); | ||
185 | |||
186 | if (fan_nr >= 3) { | ||
187 | data->fan_div[2] = (smsc47m1_read_value(data, | ||
188 | SMSC47M2_REG_FANDIV3) >> 4) & 0x03; | ||
189 | data->alarms |= (smsc47m1_read_value(data, | ||
190 | SMSC47M2_REG_ALARM6) & 0x40) >> 4; | ||
191 | /* Clear alarm if needed */ | ||
192 | if (data->alarms & 0x04) | ||
193 | smsc47m1_write_value(data, | ||
194 | SMSC47M2_REG_ALARM6, | ||
195 | 0x40); | ||
196 | } | ||
197 | |||
198 | data->last_updated = jiffies; | ||
199 | } | ||
200 | |||
201 | mutex_unlock(&data->update_lock); | ||
202 | return data; | ||
203 | } | ||
168 | 204 | ||
169 | static ssize_t get_fan(struct device *dev, struct device_attribute | 205 | static ssize_t get_fan(struct device *dev, struct device_attribute |
170 | *devattr, char *buf) | 206 | *devattr, char *buf) |
@@ -811,54 +847,13 @@ static int __exit smsc47m1_remove(struct platform_device *pdev) | |||
811 | return 0; | 847 | return 0; |
812 | } | 848 | } |
813 | 849 | ||
814 | static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, | 850 | static struct platform_driver smsc47m1_driver = { |
815 | int init) | 851 | .driver = { |
816 | { | 852 | .owner = THIS_MODULE, |
817 | struct smsc47m1_data *data = dev_get_drvdata(dev); | 853 | .name = DRVNAME, |
818 | 854 | }, | |
819 | mutex_lock(&data->update_lock); | 855 | .remove = __exit_p(smsc47m1_remove), |
820 | 856 | }; | |
821 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) { | ||
822 | int i, fan_nr; | ||
823 | fan_nr = data->type == smsc47m2 ? 3 : 2; | ||
824 | |||
825 | for (i = 0; i < fan_nr; i++) { | ||
826 | data->fan[i] = smsc47m1_read_value(data, | ||
827 | SMSC47M1_REG_FAN[i]); | ||
828 | data->fan_preload[i] = smsc47m1_read_value(data, | ||
829 | SMSC47M1_REG_FAN_PRELOAD[i]); | ||
830 | data->pwm[i] = smsc47m1_read_value(data, | ||
831 | SMSC47M1_REG_PWM[i]); | ||
832 | } | ||
833 | |||
834 | i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV); | ||
835 | data->fan_div[0] = (i >> 4) & 0x03; | ||
836 | data->fan_div[1] = i >> 6; | ||
837 | |||
838 | data->alarms = smsc47m1_read_value(data, | ||
839 | SMSC47M1_REG_ALARM) >> 6; | ||
840 | /* Clear alarms if needed */ | ||
841 | if (data->alarms) | ||
842 | smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0); | ||
843 | |||
844 | if (fan_nr >= 3) { | ||
845 | data->fan_div[2] = (smsc47m1_read_value(data, | ||
846 | SMSC47M2_REG_FANDIV3) >> 4) & 0x03; | ||
847 | data->alarms |= (smsc47m1_read_value(data, | ||
848 | SMSC47M2_REG_ALARM6) & 0x40) >> 4; | ||
849 | /* Clear alarm if needed */ | ||
850 | if (data->alarms & 0x04) | ||
851 | smsc47m1_write_value(data, | ||
852 | SMSC47M2_REG_ALARM6, | ||
853 | 0x40); | ||
854 | } | ||
855 | |||
856 | data->last_updated = jiffies; | ||
857 | } | ||
858 | |||
859 | mutex_unlock(&data->update_lock); | ||
860 | return data; | ||
861 | } | ||
862 | 857 | ||
863 | static int __init smsc47m1_device_add(unsigned short address, | 858 | static int __init smsc47m1_device_add(unsigned short address, |
864 | const struct smsc47m1_sio_data *sio_data) | 859 | const struct smsc47m1_sio_data *sio_data) |