aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/smsc47m1.c115
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
146static int __exit smsc47m1_remove(struct platform_device *pdev);
147static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
148 int init);
149
150static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg) 145static 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
161static struct platform_driver smsc47m1_driver = { 156static 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
169static ssize_t get_fan(struct device *dev, struct device_attribute 205static 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
814static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 850static 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
863static int __init smsc47m1_device_add(unsigned short address, 858static int __init smsc47m1_device_add(unsigned short address,
864 const struct smsc47m1_sio_data *sio_data) 859 const struct smsc47m1_sio_data *sio_data)