Showing error 835

User: Jiri Slaby
Error type: Resource Leak
Error type description: The code omits to put the resource to the system for reuse
File location: drivers/hwmon/via686a.c
Line in file: 866
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2011-11-07 22:40:13 UTC


Source:

  1/*
  2    via686a.c - Part of lm_sensors, Linux kernel modules
  3                for hardware monitoring
  4
  5    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
  6                        Ky��sti M��lkki <kmalkki@cc.hut.fi>,
  7                        Mark Studebaker <mdsxyz123@yahoo.com>,
  8                        and Bob Dougherty <bobd@stanford.edu>
  9    (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
 10    <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.)
 11
 12    This program is free software; you can redistribute it and/or modify
 13    it under the terms of the GNU General Public License as published by
 14    the Free Software Foundation; either version 2 of the License, or
 15    (at your option) any later version.
 16
 17    This program is distributed in the hope that it will be useful,
 18    but WITHOUT ANY WARRANTY; without even the implied warranty of
 19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20    GNU General Public License for more details.
 21
 22    You should have received a copy of the GNU General Public License
 23    along with this program; if not, write to the Free Software
 24    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 25*/
 26
 27/*
 28    Supports the Via VT82C686A, VT82C686B south bridges.
 29    Reports all as a 686A.
 30    Warning - only supports a single device.
 31*/
 32
 33#include <linux/module.h>
 34#include <linux/slab.h>
 35#include <linux/pci.h>
 36#include <linux/jiffies.h>
 37#include <linux/platform_device.h>
 38#include <linux/hwmon.h>
 39#include <linux/hwmon-sysfs.h>
 40#include <linux/err.h>
 41#include <linux/init.h>
 42#include <linux/mutex.h>
 43#include <linux/sysfs.h>
 44#include <asm/io.h>
 45
 46
 47/* If force_addr is set to anything different from 0, we forcibly enable
 48   the device at the given address. */
 49static unsigned short force_addr;
 50module_param(force_addr, ushort, 0);
 51MODULE_PARM_DESC(force_addr,
 52                 "Initialize the base address of the sensors");
 53
 54static struct platform_device *pdev;
 55
 56/*
 57   The Via 686a southbridge has a LM78-like chip integrated on the same IC.
 58   This driver is a customized copy of lm78.c
 59*/
 60
 61/* Many VIA686A constants specified below */
 62
 63/* Length of ISA address segment */
 64#define VIA686A_EXTENT                0x80
 65#define VIA686A_BASE_REG        0x70
 66#define VIA686A_ENABLE_REG        0x74
 67
 68/* The VIA686A registers */
 69/* ins numbered 0-4 */
 70#define VIA686A_REG_IN_MAX(nr)        (0x2b + ((nr) * 2))
 71#define VIA686A_REG_IN_MIN(nr)        (0x2c + ((nr) * 2))
 72#define VIA686A_REG_IN(nr)        (0x22 + (nr))
 73
 74/* fans numbered 1-2 */
 75#define VIA686A_REG_FAN_MIN(nr)        (0x3a + (nr))
 76#define VIA686A_REG_FAN(nr)        (0x28 + (nr))
 77
 78/* temps numbered 1-3 */
 79static const u8 VIA686A_REG_TEMP[]        = { 0x20, 0x21, 0x1f };
 80static const u8 VIA686A_REG_TEMP_OVER[]        = { 0x39, 0x3d, 0x1d };
 81static const u8 VIA686A_REG_TEMP_HYST[]        = { 0x3a, 0x3e, 0x1e };
 82/* bits 7-6 */
 83#define VIA686A_REG_TEMP_LOW1        0x4b
 84/* 2 = bits 5-4, 3 = bits 7-6 */
 85#define VIA686A_REG_TEMP_LOW23        0x49
 86
 87#define VIA686A_REG_ALARM1        0x41
 88#define VIA686A_REG_ALARM2        0x42
 89#define VIA686A_REG_FANDIV        0x47
 90#define VIA686A_REG_CONFIG        0x40
 91/* The following register sets temp interrupt mode (bits 1-0 for temp1,
 92 3-2 for temp2, 5-4 for temp3).  Modes are:
 93    00 interrupt stays as long as value is out-of-range
 94    01 interrupt is cleared once register is read (default)
 95    10 comparator mode- like 00, but ignores hysteresis
 96    11 same as 00 */
 97#define VIA686A_REG_TEMP_MODE                0x4b
 98/* We'll just assume that you want to set all 3 simultaneously: */
 99#define VIA686A_TEMP_MODE_MASK                0x3F
100#define VIA686A_TEMP_MODE_CONTINUOUS        0x00
101
102/* Conversions. Limit checking is only done on the TO_REG
103   variants.
104
105********* VOLTAGE CONVERSIONS (Bob Dougherty) ********
106 From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
107 voltagefactor[0]=1.25/2628; (2628/1.25=2102.4)   // Vccp
108 voltagefactor[1]=1.25/2628; (2628/1.25=2102.4)   // +2.5V
109 voltagefactor[2]=1.67/2628; (2628/1.67=1573.7)   // +3.3V
110 voltagefactor[3]=2.6/2628;  (2628/2.60=1010.8)   // +5V
111 voltagefactor[4]=6.3/2628;  (2628/6.30=417.14)   // +12V
112 in[i]=(data[i+2]*25.0+133)*voltagefactor[i];
113 That is:
114 volts = (25*regVal+133)*factor
115 regVal = (volts/factor-133)/25
116 (These conversions were contributed by Jonathan Teh Soon Yew
117 <j.teh@iname.com>) */
118static inline u8 IN_TO_REG(long val, int inNum)
119{
120        /* To avoid floating point, we multiply constants by 10 (100 for +12V).
121           Rounding is done (120500 is actually 133000 - 12500).
122           Remember that val is expressed in 0.001V/bit, which is why we divide
123           by an additional 10000 (100000 for +12V): 1000 for val and 10 (100)
124           for the constants. */
125        if (inNum <= 1)
126                return (u8)
127                    SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255);
128        else if (inNum == 2)
129                return (u8)
130                    SENSORS_LIMIT((val * 15737 - 1205000) / 250000, 0, 255);
131        else if (inNum == 3)
132                return (u8)
133                    SENSORS_LIMIT((val * 10108 - 1205000) / 250000, 0, 255);
134        else
135                return (u8)
136                    SENSORS_LIMIT((val * 41714 - 12050000) / 2500000, 0, 255);
137}
138
139static inline long IN_FROM_REG(u8 val, int inNum)
140{
141        /* To avoid floating point, we multiply constants by 10 (100 for +12V).
142           We also multiply them by 1000 because we want 0.001V/bit for the
143           output value. Rounding is done. */
144        if (inNum <= 1)
145                return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024);
146        else if (inNum == 2)
147                return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737);
148        else if (inNum == 3)
149                return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108);
150        else
151                return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714);
152}
153
154/********* FAN RPM CONVERSIONS ********/
155/* Higher register values = slower fans (the fan's strobe gates a counter).
156 But this chip saturates back at 0, not at 255 like all the other chips.
157 So, 0 means 0 RPM */
158static inline u8 FAN_TO_REG(long rpm, int div)
159{
160        if (rpm == 0)
161                return 0;
162        rpm = SENSORS_LIMIT(rpm, 1, 1000000);
163        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255);
164}
165
166#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div)))
167
168/******** TEMP CONVERSIONS (Bob Dougherty) *********/
169/* linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
170      if(temp<169)
171              return double(temp)*0.427-32.08;
172      else if(temp>=169 && temp<=202)
173              return double(temp)*0.582-58.16;
174      else
175              return double(temp)*0.924-127.33;
176
177 A fifth-order polynomial fits the unofficial data (provided by Alex van
178 Kaam <darkside@chello.nl>) a bit better.  It also give more reasonable
179 numbers on my machine (ie. they agree with what my BIOS tells me).
180 Here's the fifth-order fit to the 8-bit data:
181 temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
182        2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
183
184 (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
185 finding my typos in this formula!)
186
187 Alas, none of the elegant function-fit solutions will work because we
188 aren't allowed to use floating point in the kernel and doing it with
189 integers doesn't provide enough precision.  So we'll do boring old
190 look-up table stuff.  The unofficial data (see below) have effectively
191 7-bit resolution (they are rounded to the nearest degree).  I'm assuming
192 that the transfer function of the device is monotonic and smooth, so a
193 smooth function fit to the data will allow us to get better precision.
194 I used the 5th-order poly fit described above and solved for
195 VIA register values 0-255.  I *10 before rounding, so we get tenth-degree
196 precision.  (I could have done all 1024 values for our 10-bit readings,
197 but the function is very linear in the useful range (0-80 deg C), so
198 we'll just use linear interpolation for 10-bit readings.)  So, tempLUT
199 is the temp at via register values 0-255: */
200static const s16 tempLUT[] =
201{ -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
202        -503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
203        -362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
204        -255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
205        -173, -166, -159, -152, -145, -139, -132, -126, -120, -114,
206        -108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49,
207        -44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16,
208        20, 25, 29, 33, 37, 42, 46, 50, 54, 59, 63, 67, 71, 75, 79, 84,
209        88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138,
210        142, 146, 151, 155, 159, 163, 168, 172, 176, 181, 185, 189,
211        193, 198, 202, 206, 211, 215, 219, 224, 228, 232, 237, 241,
212        245, 250, 254, 259, 263, 267, 272, 276, 281, 285, 290, 294,
213        299, 303, 307, 312, 316, 321, 325, 330, 334, 339, 344, 348,
214        353, 357, 362, 366, 371, 376, 380, 385, 390, 395, 399, 404,
215        409, 414, 419, 423, 428, 433, 438, 443, 449, 454, 459, 464,
216        469, 475, 480, 486, 491, 497, 502, 508, 514, 520, 526, 532,
217        538, 544, 551, 557, 564, 571, 578, 584, 592, 599, 606, 614,
218        621, 629, 637, 645, 654, 662, 671, 680, 689, 698, 708, 718,
219        728, 738, 749, 759, 770, 782, 793, 805, 818, 830, 843, 856,
220        870, 883, 898, 912, 927, 943, 958, 975, 991, 1008, 1026, 1044,
221        1062, 1081, 1101, 1121, 1141, 1162, 1184, 1206, 1229, 1252,
222        1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462
223};
224
225/* the original LUT values from Alex van Kaam <darkside@chello.nl>
226   (for via register values 12-240):
227{-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
228-30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
229-15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
230-3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,
23112,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,
23222,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,
23333,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,
23445,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60,
23561,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,
23685,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110};
237
238
239 Here's the reverse LUT.  I got it by doing a 6-th order poly fit (needed
240 an extra term for a good fit to these inverse data!) and then
241 solving for each temp value from -50 to 110 (the useable range for
242 this chip).  Here's the fit:
243 viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4
244 - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
245 Note that n=161: */
246static const u8 viaLUT[] =
247{ 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
248        23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40,
249        41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66,
250        69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100,
251        103, 105, 107, 110, 112, 115, 117, 119, 122, 124, 126, 129,
252        131, 134, 136, 138, 140, 143, 145, 147, 150, 152, 154, 156,
253        158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180,
254        182, 183, 185, 187, 188, 190, 192, 193, 195, 196, 198, 199,
255        200, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213,
256        214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224,
257        225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232,
258        233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
259        239, 240
260};
261
262/* Converting temps to (8-bit) hyst and over registers
263   No interpolation here.
264   The +50 is because the temps start at -50 */
265static inline u8 TEMP_TO_REG(long val)
266{
267        return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 :
268                      (val < 0 ? val - 500 : val + 500) / 1000 + 50];
269}
270
271/* for 8-bit temperature hyst and over registers */
272#define TEMP_FROM_REG(val)        ((long)tempLUT[val] * 100)
273
274/* for 10-bit temperature readings */
275static inline long TEMP_FROM_REG10(u16 val)
276{
277        u16 eightBits = val >> 2;
278        u16 twoBits = val & 3;
279
280        /* no interpolation for these */
281        if (twoBits == 0 || eightBits == 255)
282                return TEMP_FROM_REG(eightBits);
283
284        /* do some linear interpolation */
285        return (tempLUT[eightBits] * (4 - twoBits) +
286                tempLUT[eightBits + 1] * twoBits) * 25;
287}
288
289#define DIV_FROM_REG(val) (1 << (val))
290#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
291
292/* For each registered chip, we need to keep some data in memory.
293   The structure is dynamically allocated. */
294struct via686a_data {
295        unsigned short addr;
296        const char *name;
297        struct device *hwmon_dev;
298        struct mutex update_lock;
299        char valid;                /* !=0 if following fields are valid */
300        unsigned long last_updated;        /* In jiffies */
301
302        u8 in[5];                /* Register value */
303        u8 in_max[5];                /* Register value */
304        u8 in_min[5];                /* Register value */
305        u8 fan[2];                /* Register value */
306        u8 fan_min[2];                /* Register value */
307        u16 temp[3];                /* Register value 10 bit */
308        u8 temp_over[3];        /* Register value */
309        u8 temp_hyst[3];        /* Register value */
310        u8 fan_div[2];                /* Register encoding, shifted right */
311        u16 alarms;                /* Register encoding, combined */
312};
313
314static struct pci_dev *s_bridge;        /* pointer to the (only) via686a */
315
316static int via686a_probe(struct platform_device *pdev);
317static int __devexit via686a_remove(struct platform_device *pdev);
318
319static inline int via686a_read_value(struct via686a_data *data, u8 reg)
320{
321        return inb_p(data->addr + reg);
322}
323
324static inline void via686a_write_value(struct via686a_data *data, u8 reg,
325                                       u8 value)
326{
327        outb_p(value, data->addr + reg);
328}
329
330static struct via686a_data *via686a_update_device(struct device *dev);
331static void via686a_init_device(struct via686a_data *data);
332
333/* following are the sysfs callback functions */
334
335/* 7 voltage sensors */
336static ssize_t show_in(struct device *dev, struct device_attribute *da,
337                char *buf) {
338        struct via686a_data *data = via686a_update_device(dev);
339        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
340        int nr = attr->index;
341        return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr));
342}
343
344static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
345                char *buf) {
346        struct via686a_data *data = via686a_update_device(dev);
347        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
348        int nr = attr->index;
349        return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr));
350}
351
352static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
353                char *buf) {
354        struct via686a_data *data = via686a_update_device(dev);
355        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
356        int nr = attr->index;
357        return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr));
358}
359
360static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
361                const char *buf, size_t count) {
362        struct via686a_data *data = dev_get_drvdata(dev);
363        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
364        int nr = attr->index;
365        unsigned long val = simple_strtoul(buf, NULL, 10);
366
367        mutex_lock(&data->update_lock);
368        data->in_min[nr] = IN_TO_REG(val, nr);
369        via686a_write_value(data, VIA686A_REG_IN_MIN(nr),
370                        data->in_min[nr]);
371        mutex_unlock(&data->update_lock);
372        return count;
373}
374static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
375                const char *buf, size_t count) {
376        struct via686a_data *data = dev_get_drvdata(dev);
377        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
378        int nr = attr->index;
379        unsigned long val = simple_strtoul(buf, NULL, 10);
380
381        mutex_lock(&data->update_lock);
382        data->in_max[nr] = IN_TO_REG(val, nr);
383        via686a_write_value(data, VIA686A_REG_IN_MAX(nr),
384                        data->in_max[nr]);
385        mutex_unlock(&data->update_lock);
386        return count;
387}
388#define show_in_offset(offset)                                        \
389static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,                \
390                show_in, NULL, offset);                                \
391static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,        \
392                show_in_min, set_in_min, offset);                \
393static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,        \
394                show_in_max, set_in_max, offset);
395
396show_in_offset(0);
397show_in_offset(1);
398show_in_offset(2);
399show_in_offset(3);
400show_in_offset(4);
401
402/* 3 temperatures */
403static ssize_t show_temp(struct device *dev, struct device_attribute *da,
404                char *buf) {
405        struct via686a_data *data = via686a_update_device(dev);
406        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
407        int nr = attr->index;
408        return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr]));
409}
410static ssize_t show_temp_over(struct device *dev, struct device_attribute *da,
411                char *buf) {
412        struct via686a_data *data = via686a_update_device(dev);
413        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
414        int nr = attr->index;
415        return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr]));
416}
417static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da,
418                char *buf) {
419        struct via686a_data *data = via686a_update_device(dev);
420        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
421        int nr = attr->index;
422        return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr]));
423}
424static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
425                const char *buf, size_t count) {
426        struct via686a_data *data = dev_get_drvdata(dev);
427        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
428        int nr = attr->index;
429        int val = simple_strtol(buf, NULL, 10);
430
431        mutex_lock(&data->update_lock);
432        data->temp_over[nr] = TEMP_TO_REG(val);
433        via686a_write_value(data, VIA686A_REG_TEMP_OVER[nr],
434                            data->temp_over[nr]);
435        mutex_unlock(&data->update_lock);
436        return count;
437}
438static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
439                const char *buf, size_t count) {
440        struct via686a_data *data = dev_get_drvdata(dev);
441        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
442        int nr = attr->index;
443        int val = simple_strtol(buf, NULL, 10);
444
445        mutex_lock(&data->update_lock);
446        data->temp_hyst[nr] = TEMP_TO_REG(val);
447        via686a_write_value(data, VIA686A_REG_TEMP_HYST[nr],
448                            data->temp_hyst[nr]);
449        mutex_unlock(&data->update_lock);
450        return count;
451}
452#define show_temp_offset(offset)                                        \
453static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,                \
454                show_temp, NULL, offset - 1);                                \
455static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,        \
456                show_temp_over, set_temp_over, offset - 1);                \
457static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR,        \
458                show_temp_hyst, set_temp_hyst, offset - 1);
459
460show_temp_offset(1);
461show_temp_offset(2);
462show_temp_offset(3);
463
464/* 2 Fans */
465static ssize_t show_fan(struct device *dev, struct device_attribute *da,
466                char *buf) {
467        struct via686a_data *data = via686a_update_device(dev);
468        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
469        int nr = attr->index;
470        return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
471                                DIV_FROM_REG(data->fan_div[nr])) );
472}
473static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
474                char *buf) {
475        struct via686a_data *data = via686a_update_device(dev);
476        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
477        int nr = attr->index;
478        return sprintf(buf, "%d\n",
479                FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
480}
481static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
482                char *buf) {
483        struct via686a_data *data = via686a_update_device(dev);
484        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
485        int nr = attr->index;
486        return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
487}
488static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
489                const char *buf, size_t count) {
490        struct via686a_data *data = dev_get_drvdata(dev);
491        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
492        int nr = attr->index;
493        int val = simple_strtol(buf, NULL, 10);
494
495        mutex_lock(&data->update_lock);
496        data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
497        via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
498        mutex_unlock(&data->update_lock);
499        return count;
500}
501static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
502                const char *buf, size_t count) {
503        struct via686a_data *data = dev_get_drvdata(dev);
504        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
505        int nr = attr->index;
506        int val = simple_strtol(buf, NULL, 10);
507        int old;
508
509        mutex_lock(&data->update_lock);
510        old = via686a_read_value(data, VIA686A_REG_FANDIV);
511        data->fan_div[nr] = DIV_TO_REG(val);
512        old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
513        via686a_write_value(data, VIA686A_REG_FANDIV, old);
514        mutex_unlock(&data->update_lock);
515        return count;
516}
517
518#define show_fan_offset(offset)                                                \
519static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,                        \
520                show_fan, NULL, offset - 1);                                \
521static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,                \
522                show_fan_min, set_fan_min, offset - 1);                        \
523static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,                \
524                show_fan_div, set_fan_div, offset - 1);
525
526show_fan_offset(1);
527show_fan_offset(2);
528
529/* Alarms */
530static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) {
531        struct via686a_data *data = via686a_update_device(dev);
532        return sprintf(buf, "%u\n", data->alarms);
533}
534static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
535
536static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
537                          char *buf)
538{
539        int bitnr = to_sensor_dev_attr(attr)->index;
540        struct via686a_data *data = via686a_update_device(dev);
541        return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
542}
543static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
544static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
545static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
546static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
547static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
548static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
549static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 11);
550static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 15);
551static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
552static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
553
554static ssize_t show_name(struct device *dev, struct device_attribute
555                         *devattr, char *buf)
556{
557        struct via686a_data *data = dev_get_drvdata(dev);
558        return sprintf(buf, "%s\n", data->name);
559}
560static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
561
562static struct attribute *via686a_attributes[] = {
563        &sensor_dev_attr_in0_input.dev_attr.attr,
564        &sensor_dev_attr_in1_input.dev_attr.attr,
565        &sensor_dev_attr_in2_input.dev_attr.attr,
566        &sensor_dev_attr_in3_input.dev_attr.attr,
567        &sensor_dev_attr_in4_input.dev_attr.attr,
568        &sensor_dev_attr_in0_min.dev_attr.attr,
569        &sensor_dev_attr_in1_min.dev_attr.attr,
570        &sensor_dev_attr_in2_min.dev_attr.attr,
571        &sensor_dev_attr_in3_min.dev_attr.attr,
572        &sensor_dev_attr_in4_min.dev_attr.attr,
573        &sensor_dev_attr_in0_max.dev_attr.attr,
574        &sensor_dev_attr_in1_max.dev_attr.attr,
575        &sensor_dev_attr_in2_max.dev_attr.attr,
576        &sensor_dev_attr_in3_max.dev_attr.attr,
577        &sensor_dev_attr_in4_max.dev_attr.attr,
578        &sensor_dev_attr_in0_alarm.dev_attr.attr,
579        &sensor_dev_attr_in1_alarm.dev_attr.attr,
580        &sensor_dev_attr_in2_alarm.dev_attr.attr,
581        &sensor_dev_attr_in3_alarm.dev_attr.attr,
582        &sensor_dev_attr_in4_alarm.dev_attr.attr,
583
584        &sensor_dev_attr_temp1_input.dev_attr.attr,
585        &sensor_dev_attr_temp2_input.dev_attr.attr,
586        &sensor_dev_attr_temp3_input.dev_attr.attr,
587        &sensor_dev_attr_temp1_max.dev_attr.attr,
588        &sensor_dev_attr_temp2_max.dev_attr.attr,
589        &sensor_dev_attr_temp3_max.dev_attr.attr,
590        &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
591        &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
592        &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
593        &sensor_dev_attr_temp1_alarm.dev_attr.attr,
594        &sensor_dev_attr_temp2_alarm.dev_attr.attr,
595        &sensor_dev_attr_temp3_alarm.dev_attr.attr,
596
597        &sensor_dev_attr_fan1_input.dev_attr.attr,
598        &sensor_dev_attr_fan2_input.dev_attr.attr,
599        &sensor_dev_attr_fan1_min.dev_attr.attr,
600        &sensor_dev_attr_fan2_min.dev_attr.attr,
601        &sensor_dev_attr_fan1_div.dev_attr.attr,
602        &sensor_dev_attr_fan2_div.dev_attr.attr,
603        &sensor_dev_attr_fan1_alarm.dev_attr.attr,
604        &sensor_dev_attr_fan2_alarm.dev_attr.attr,
605
606        &dev_attr_alarms.attr,
607        &dev_attr_name.attr,
608        NULL
609};
610
611static const struct attribute_group via686a_group = {
612        .attrs = via686a_attributes,
613};
614
615static struct platform_driver via686a_driver = {
616        .driver = {
617                .owner        = THIS_MODULE,
618                .name        = "via686a",
619        },
620        .probe                = via686a_probe,
621        .remove                = __devexit_p(via686a_remove),
622};
623
624
625/* This is called when the module is loaded */
626static int __devinit via686a_probe(struct platform_device *pdev)
627{
628        struct via686a_data *data;
629        struct resource *res;
630        int err;
631
632        /* Reserve the ISA region */
633        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
634        if (!request_region(res->start, VIA686A_EXTENT,
635                            via686a_driver.driver.name)) {
636                dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n",
637                        (unsigned long)res->start, (unsigned long)res->end);
638                return -ENODEV;
639        }
640
641        if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
642                err = -ENOMEM;
643                goto exit_release;
644        }
645
646        platform_set_drvdata(pdev, data);
647        data->addr = res->start;
648        data->name = "via686a";
649        mutex_init(&data->update_lock);
650
651        /* Initialize the VIA686A chip */
652        via686a_init_device(data);
653
654        /* Register sysfs hooks */
655        if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group)))
656                goto exit_free;
657
658        data->hwmon_dev = hwmon_device_register(&pdev->dev);
659        if (IS_ERR(data->hwmon_dev)) {
660                err = PTR_ERR(data->hwmon_dev);
661                goto exit_remove_files;
662        }
663
664        return 0;
665
666exit_remove_files:
667        sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
668exit_free:
669        kfree(data);
670exit_release:
671        release_region(res->start, VIA686A_EXTENT);
672        return err;
673}
674
675static int __devexit via686a_remove(struct platform_device *pdev)
676{
677        struct via686a_data *data = platform_get_drvdata(pdev);
678
679        hwmon_device_unregister(data->hwmon_dev);
680        sysfs_remove_group(&pdev->dev.kobj, &via686a_group);
681
682        release_region(data->addr, VIA686A_EXTENT);
683        platform_set_drvdata(pdev, NULL);
684        kfree(data);
685
686        return 0;
687}
688
689static void __devinit via686a_init_device(struct via686a_data *data)
690{
691        u8 reg;
692
693        /* Start monitoring */
694        reg = via686a_read_value(data, VIA686A_REG_CONFIG);
695        via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F);
696
697        /* Configure temp interrupt mode for continuous-interrupt operation */
698        reg = via686a_read_value(data, VIA686A_REG_TEMP_MODE);
699        via686a_write_value(data, VIA686A_REG_TEMP_MODE,
700                            (reg & ~VIA686A_TEMP_MODE_MASK)
701                            | VIA686A_TEMP_MODE_CONTINUOUS);
702}
703
704static struct via686a_data *via686a_update_device(struct device *dev)
705{
706        struct via686a_data *data = dev_get_drvdata(dev);
707        int i;
708
709        mutex_lock(&data->update_lock);
710
711        if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
712            || !data->valid) {
713                for (i = 0; i <= 4; i++) {
714                        data->in[i] =
715                            via686a_read_value(data, VIA686A_REG_IN(i));
716                        data->in_min[i] = via686a_read_value(data,
717                                                             VIA686A_REG_IN_MIN
718                                                             (i));
719                        data->in_max[i] =
720                            via686a_read_value(data, VIA686A_REG_IN_MAX(i));
721                }
722                for (i = 1; i <= 2; i++) {
723                        data->fan[i - 1] =
724                            via686a_read_value(data, VIA686A_REG_FAN(i));
725                        data->fan_min[i - 1] = via686a_read_value(data,
726                                                     VIA686A_REG_FAN_MIN(i));
727                }
728                for (i = 0; i <= 2; i++) {
729                        data->temp[i] = via686a_read_value(data,
730                                                 VIA686A_REG_TEMP[i]) << 2;
731                        data->temp_over[i] =
732                            via686a_read_value(data,
733                                               VIA686A_REG_TEMP_OVER[i]);
734                        data->temp_hyst[i] =
735                            via686a_read_value(data,
736                                               VIA686A_REG_TEMP_HYST[i]);
737                }
738                /* add in lower 2 bits
739                   temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1
740                   temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23
741                   temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23
742                 */
743                data->temp[0] |= (via686a_read_value(data,
744                                                     VIA686A_REG_TEMP_LOW1)
745                                  & 0xc0) >> 6;
746                data->temp[1] |=
747                    (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
748                     0x30) >> 4;
749                data->temp[2] |=
750                    (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) &
751                     0xc0) >> 6;
752
753                i = via686a_read_value(data, VIA686A_REG_FANDIV);
754                data->fan_div[0] = (i >> 4) & 0x03;
755                data->fan_div[1] = i >> 6;
756                data->alarms =
757                    via686a_read_value(data,
758                                       VIA686A_REG_ALARM1) |
759                    (via686a_read_value(data, VIA686A_REG_ALARM2) << 8);
760                data->last_updated = jiffies;
761                data->valid = 1;
762        }
763
764        mutex_unlock(&data->update_lock);
765
766        return data;
767}
768
769static struct pci_device_id via686a_pci_ids[] = {
770        { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
771        { 0, }
772};
773
774MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
775
776static int __devinit via686a_device_add(unsigned short address)
777{
778        struct resource res = {
779                .start        = address,
780                .end        = address + VIA686A_EXTENT - 1,
781                .name        = "via686a",
782                .flags        = IORESOURCE_IO,
783        };
784        int err;
785
786        pdev = platform_device_alloc("via686a", address);
787        if (!pdev) {
788                err = -ENOMEM;
789                printk(KERN_ERR "via686a: Device allocation failed\n");
790                goto exit;
791        }
792
793        err = platform_device_add_resources(pdev, &res, 1);
794        if (err) {
795                printk(KERN_ERR "via686a: Device resource addition failed "
796                       "(%d)\n", err);
797                goto exit_device_put;
798        }
799
800        err = platform_device_add(pdev);
801        if (err) {
802                printk(KERN_ERR "via686a: Device addition failed (%d)\n",
803                       err);
804                goto exit_device_put;
805        }
806
807        return 0;
808
809exit_device_put:
810        platform_device_put(pdev);
811exit:
812        return err;
813}
814
815static int __devinit via686a_pci_probe(struct pci_dev *dev,
816                                       const struct pci_device_id *id)
817{
818        u16 address, val;
819
820        if (force_addr) {
821                address = force_addr & ~(VIA686A_EXTENT - 1);
822                dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address);
823                if (PCIBIOS_SUCCESSFUL !=
824                    pci_write_config_word(dev, VIA686A_BASE_REG, address | 1))
825                        return -ENODEV;
826        }
827        if (PCIBIOS_SUCCESSFUL !=
828            pci_read_config_word(dev, VIA686A_BASE_REG, &val))
829                return -ENODEV;
830
831        address = val & ~(VIA686A_EXTENT - 1);
832        if (address == 0) {
833                dev_err(&dev->dev, "base address not set - upgrade BIOS "
834                        "or use force_addr=0xaddr\n");
835                return -ENODEV;
836        }
837
838        if (PCIBIOS_SUCCESSFUL !=
839            pci_read_config_word(dev, VIA686A_ENABLE_REG, &val))
840                return -ENODEV;
841        if (!(val & 0x0001)) {
842                if (!force_addr) {
843                        dev_warn(&dev->dev, "Sensors disabled, enable "
844                                 "with force_addr=0x%x\n", address);
845                        return -ENODEV;
846                }
847
848                dev_warn(&dev->dev, "Enabling sensors\n");
849                if (PCIBIOS_SUCCESSFUL !=
850                    pci_write_config_word(dev, VIA686A_ENABLE_REG,
851                                          val | 0x0001))
852                        return -ENODEV;
853        }
854
855        if (platform_driver_register(&via686a_driver))
856                goto exit;
857
858        /* Sets global pdev as a side effect */
859        if (via686a_device_add(address))
860                goto exit_unregister;
861
862        /* Always return failure here.  This is to allow other drivers to bind
863         * to this pci device.  We don't really want to have control over the
864         * pci device, we only wanted to read as few register values from it.
865         */
866        s_bridge = pci_dev_get(dev);
867        return -ENODEV;
868
869exit_unregister:
870        platform_driver_unregister(&via686a_driver);
871exit:
872        return -ENODEV;
873}
874
875static struct pci_driver via686a_pci_driver = {
876        .name                = "via686a",
877        .id_table        = via686a_pci_ids,
878        .probe                = via686a_pci_probe,
879};
880
881static int __init sm_via686a_init(void)
882{
883        return pci_register_driver(&via686a_pci_driver);
884}
885
886static void __exit sm_via686a_exit(void)
887{
888        pci_unregister_driver(&via686a_pci_driver);
889        if (s_bridge != NULL) {
890                platform_device_unregister(pdev);
891                platform_driver_unregister(&via686a_driver);
892                pci_dev_put(s_bridge);
893                s_bridge = NULL;
894        }
895}
896
897MODULE_AUTHOR("Ky��sti M��lkki <kmalkki@cc.hut.fi>, "
898              "Mark Studebaker <mdsxyz123@yahoo.com> "
899              "and Bob Dougherty <bobd@stanford.edu>");
900MODULE_DESCRIPTION("VIA 686A Sensor device");
901MODULE_LICENSE("GPL");
902
903module_init(sm_via686a_init);
904module_exit(sm_via686a_exit);