Pull video into release branch
[sfrench/cifs-2.6.git] / drivers / hwmon / pc87427.c
1 /*
2  *  pc87427.c - hardware monitoring driver for the
3  *              National Semiconductor PC87427 Super-I/O chip
4  *  Copyright (C) 2006 Jean Delvare <khali@linux-fr.org>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License version 2 as
8  *  published by the Free Software Foundation.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  Supports the following chips:
16  *
17  *  Chip        #vin    #fan    #pwm    #temp   devid
18  *  PC87427     -       8       -       -       0xF2
19  *
20  *  This driver assumes that no more than one chip is present.
21  *  Only fan inputs are supported so far, although the chip can do much more.
22  */
23
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/slab.h>
27 #include <linux/jiffies.h>
28 #include <linux/platform_device.h>
29 #include <linux/hwmon.h>
30 #include <linux/hwmon-sysfs.h>
31 #include <linux/err.h>
32 #include <linux/mutex.h>
33 #include <linux/sysfs.h>
34 #include <linux/ioport.h>
35 #include <asm/io.h>
36
37 static struct platform_device *pdev;
38
39 #define DRVNAME "pc87427"
40
41 /* The lock mutex protects both the I/O accesses (needed because the
42    device is using banked registers) and the register cache (needed to keep
43    the data in the registers and the cache in sync at any time). */
44 struct pc87427_data {
45         struct class_device *class_dev;
46         struct mutex lock;
47         int address[2];
48         const char *name;
49
50         unsigned long last_updated;     /* in jiffies */
51         u8 fan_enabled;                 /* bit vector */
52         u16 fan[8];                     /* register values */
53         u16 fan_min[8];                 /* register values */
54         u8 fan_status[8];               /* register values */
55 };
56
57 /*
58  * Super-I/O registers and operations
59  */
60
61 #define SIOREG_LDSEL    0x07    /* Logical device select */
62 #define SIOREG_DEVID    0x20    /* Device ID */
63 #define SIOREG_ACT      0x30    /* Device activation */
64 #define SIOREG_MAP      0x50    /* I/O or memory mapping */
65 #define SIOREG_IOBASE   0x60    /* I/O base address */
66
67 static const u8 logdev[2] = { 0x09, 0x14 };
68 static const char *logdev_str[2] = { DRVNAME " FMC", DRVNAME " HMC" };
69 #define LD_FAN          0
70 #define LD_IN           1
71 #define LD_TEMP         1
72
73 static inline void superio_outb(int sioaddr, int reg, int val)
74 {
75         outb(reg, sioaddr);
76         outb(val, sioaddr + 1);
77 }
78
79 static inline int superio_inb(int sioaddr, int reg)
80 {
81         outb(reg, sioaddr);
82         return inb(sioaddr + 1);
83 }
84
85 static inline void superio_exit(int sioaddr)
86 {
87         outb(0x02, sioaddr);
88         outb(0x02, sioaddr + 1);
89 }
90
91 /*
92  * Logical devices
93  */
94
95 #define REGION_LENGTH           32
96 #define PC87427_REG_BANK        0x0f
97 #define BANK_FM(nr)             (nr)
98 #define BANK_FT(nr)             (0x08 + (nr))
99 #define BANK_FC(nr)             (0x10 + (nr) * 2)
100
101 /*
102  * I/O access functions
103  */
104
105 /* ldi is the logical device index */
106 static inline int pc87427_read8(struct pc87427_data *data, u8 ldi, u8 reg)
107 {
108         return inb(data->address[ldi] + reg);
109 }
110
111 /* Must be called with data->lock held, except during init */
112 static inline int pc87427_read8_bank(struct pc87427_data *data, u8 ldi,
113                                      u8 bank, u8 reg)
114 {
115         outb(bank, data->address[ldi] + PC87427_REG_BANK);
116         return inb(data->address[ldi] + reg);
117 }
118
119 /* Must be called with data->lock held, except during init */
120 static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi,
121                                        u8 bank, u8 reg, u8 value)
122 {
123         outb(bank, data->address[ldi] + PC87427_REG_BANK);
124         outb(value, data->address[ldi] + reg);
125 }
126
127 /*
128  * Fan registers and conversions
129  */
130
131 /* fan data registers are 16-bit wide */
132 #define PC87427_REG_FAN                 0x12
133 #define PC87427_REG_FAN_MIN             0x14
134 #define PC87427_REG_FAN_STATUS          0x10
135
136 #define FAN_STATUS_STALL                (1 << 3)
137 #define FAN_STATUS_LOSPD                (1 << 1)
138 #define FAN_STATUS_MONEN                (1 << 0)
139
140 /* Dedicated function to read all registers related to a given fan input.
141    This saves us quite a few locks and bank selections.
142    Must be called with data->lock held.
143    nr is from 0 to 7 */
144 static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
145 {
146         int iobase = data->address[LD_FAN];
147
148         outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
149         data->fan[nr] = inw(iobase + PC87427_REG_FAN);
150         data->fan_min[nr] = inw(iobase + PC87427_REG_FAN_MIN);
151         data->fan_status[nr] = inb(iobase + PC87427_REG_FAN_STATUS);
152         /* Clear fan alarm bits */
153         outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS);
154 }
155
156 /* The 2 LSB of fan speed registers are used for something different.
157    The actual 2 LSB of the measurements are not available. */
158 static inline unsigned long fan_from_reg(u16 reg)
159 {
160         reg &= 0xfffc;
161         if (reg == 0x0000 || reg == 0xfffc)
162                 return 0;
163         return 5400000UL / reg;
164 }
165
166 /* The 2 LSB of the fan speed limit registers are not significant. */
167 static inline u16 fan_to_reg(unsigned long val)
168 {
169         if (val < 83UL)
170                 return 0xffff;
171         if (val >= 1350000UL)
172                 return 0x0004;
173         return ((1350000UL + val / 2) / val) << 2;
174 }
175
176 /*
177  * Data interface
178  */
179
180 static struct pc87427_data *pc87427_update_device(struct device *dev)
181 {
182         struct pc87427_data *data = dev_get_drvdata(dev);
183         int i;
184
185         mutex_lock(&data->lock);
186         if (!time_after(jiffies, data->last_updated + HZ)
187          && data->last_updated)
188                 goto done;
189
190         /* Fans */
191         for (i = 0; i < 8; i++) {
192                 if (!(data->fan_enabled & (1 << i)))
193                         continue;
194                 pc87427_readall_fan(data, i);
195         }
196         data->last_updated = jiffies;
197
198 done:
199         mutex_unlock(&data->lock);
200         return data;
201 }
202
203 static ssize_t show_fan_input(struct device *dev, struct device_attribute
204                               *devattr, char *buf)
205 {
206         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
207         struct pc87427_data *data = pc87427_update_device(dev);
208         int nr = attr->index;
209
210         return sprintf(buf, "%lu\n", fan_from_reg(data->fan[nr]));
211 }
212
213 static ssize_t show_fan_min(struct device *dev, struct device_attribute
214                             *devattr, char *buf)
215 {
216         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
217         struct pc87427_data *data = pc87427_update_device(dev);
218         int nr = attr->index;
219
220         return sprintf(buf, "%lu\n", fan_from_reg(data->fan_min[nr]));
221 }
222
223 static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
224                               *devattr, char *buf)
225 {
226         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
227         struct pc87427_data *data = pc87427_update_device(dev);
228         int nr = attr->index;
229
230         return sprintf(buf, "%d\n", !!(data->fan_status[nr]
231                                        & FAN_STATUS_LOSPD));
232 }
233
234 static ssize_t show_fan_fault(struct device *dev, struct device_attribute
235                               *devattr, char *buf)
236 {
237         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
238         struct pc87427_data *data = pc87427_update_device(dev);
239         int nr = attr->index;
240
241         return sprintf(buf, "%d\n", !!(data->fan_status[nr]
242                                        & FAN_STATUS_STALL));
243 }
244
245 static ssize_t set_fan_min(struct device *dev, struct device_attribute
246                            *devattr, const char *buf, size_t count)
247 {
248         struct pc87427_data *data = dev_get_drvdata(dev);
249         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
250         int nr = attr->index;
251         unsigned long val = simple_strtoul(buf, NULL, 10);
252         int iobase = data->address[LD_FAN];
253
254         mutex_lock(&data->lock);
255         outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
256         /* The low speed limit registers are read-only while monitoring
257            is enabled, so we have to disable monitoring, then change the
258            limit, and finally enable monitoring again. */
259         outb(0, iobase + PC87427_REG_FAN_STATUS);
260         data->fan_min[nr] = fan_to_reg(val);
261         outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN);
262         outb(FAN_STATUS_MONEN, iobase + PC87427_REG_FAN_STATUS);
263         mutex_unlock(&data->lock);
264
265         return count;
266 }
267
268 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
269 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
270 static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2);
271 static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3);
272 static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan_input, NULL, 4);
273 static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan_input, NULL, 5);
274 static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan_input, NULL, 6);
275 static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan_input, NULL, 7);
276
277 static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO,
278                           show_fan_min, set_fan_min, 0);
279 static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO,
280                           show_fan_min, set_fan_min, 1);
281 static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
282                           show_fan_min, set_fan_min, 2);
283 static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
284                           show_fan_min, set_fan_min, 3);
285 static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO,
286                           show_fan_min, set_fan_min, 4);
287 static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO,
288                           show_fan_min, set_fan_min, 5);
289 static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO,
290                           show_fan_min, set_fan_min, 6);
291 static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO,
292                           show_fan_min, set_fan_min, 7);
293
294 static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0);
295 static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1);
296 static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2);
297 static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3);
298 static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_fan_alarm, NULL, 4);
299 static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_fan_alarm, NULL, 5);
300 static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_fan_alarm, NULL, 6);
301 static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_fan_alarm, NULL, 7);
302
303 static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
304 static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
305 static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
306 static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
307 static SENSOR_DEVICE_ATTR(fan5_fault, S_IRUGO, show_fan_fault, NULL, 4);
308 static SENSOR_DEVICE_ATTR(fan6_fault, S_IRUGO, show_fan_fault, NULL, 5);
309 static SENSOR_DEVICE_ATTR(fan7_fault, S_IRUGO, show_fan_fault, NULL, 6);
310 static SENSOR_DEVICE_ATTR(fan8_fault, S_IRUGO, show_fan_fault, NULL, 7);
311
312 static struct attribute *pc87427_attributes_fan[8][5] = {
313         {
314                 &sensor_dev_attr_fan1_input.dev_attr.attr,
315                 &sensor_dev_attr_fan1_min.dev_attr.attr,
316                 &sensor_dev_attr_fan1_alarm.dev_attr.attr,
317                 &sensor_dev_attr_fan1_fault.dev_attr.attr,
318                 NULL
319         }, {
320                 &sensor_dev_attr_fan2_input.dev_attr.attr,
321                 &sensor_dev_attr_fan2_min.dev_attr.attr,
322                 &sensor_dev_attr_fan2_alarm.dev_attr.attr,
323                 &sensor_dev_attr_fan2_fault.dev_attr.attr,
324                 NULL
325         }, {
326                 &sensor_dev_attr_fan3_input.dev_attr.attr,
327                 &sensor_dev_attr_fan3_min.dev_attr.attr,
328                 &sensor_dev_attr_fan3_alarm.dev_attr.attr,
329                 &sensor_dev_attr_fan3_fault.dev_attr.attr,
330                 NULL
331         }, {
332                 &sensor_dev_attr_fan4_input.dev_attr.attr,
333                 &sensor_dev_attr_fan4_min.dev_attr.attr,
334                 &sensor_dev_attr_fan4_alarm.dev_attr.attr,
335                 &sensor_dev_attr_fan4_fault.dev_attr.attr,
336                 NULL
337         }, {
338                 &sensor_dev_attr_fan5_input.dev_attr.attr,
339                 &sensor_dev_attr_fan5_min.dev_attr.attr,
340                 &sensor_dev_attr_fan5_alarm.dev_attr.attr,
341                 &sensor_dev_attr_fan5_fault.dev_attr.attr,
342                 NULL
343         }, {
344                 &sensor_dev_attr_fan6_input.dev_attr.attr,
345                 &sensor_dev_attr_fan6_min.dev_attr.attr,
346                 &sensor_dev_attr_fan6_alarm.dev_attr.attr,
347                 &sensor_dev_attr_fan6_fault.dev_attr.attr,
348                 NULL
349         }, {
350                 &sensor_dev_attr_fan7_input.dev_attr.attr,
351                 &sensor_dev_attr_fan7_min.dev_attr.attr,
352                 &sensor_dev_attr_fan7_alarm.dev_attr.attr,
353                 &sensor_dev_attr_fan7_fault.dev_attr.attr,
354                 NULL
355         }, {
356                 &sensor_dev_attr_fan8_input.dev_attr.attr,
357                 &sensor_dev_attr_fan8_min.dev_attr.attr,
358                 &sensor_dev_attr_fan8_alarm.dev_attr.attr,
359                 &sensor_dev_attr_fan8_fault.dev_attr.attr,
360                 NULL
361         }
362 };
363
364 static const struct attribute_group pc87427_group_fan[8] = {
365         { .attrs = pc87427_attributes_fan[0] },
366         { .attrs = pc87427_attributes_fan[1] },
367         { .attrs = pc87427_attributes_fan[2] },
368         { .attrs = pc87427_attributes_fan[3] },
369         { .attrs = pc87427_attributes_fan[4] },
370         { .attrs = pc87427_attributes_fan[5] },
371         { .attrs = pc87427_attributes_fan[6] },
372         { .attrs = pc87427_attributes_fan[7] },
373 };
374
375 static ssize_t show_name(struct device *dev, struct device_attribute
376                          *devattr, char *buf)
377 {
378         struct pc87427_data *data = dev_get_drvdata(dev);
379
380         return sprintf(buf, "%s\n", data->name);
381 }
382 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
383
384
385 /*
386  * Device detection, attach and detach
387  */
388
389 static void __devinit pc87427_init_device(struct device *dev)
390 {
391         struct pc87427_data *data = dev_get_drvdata(dev);
392         int i;
393         u8 reg;
394
395         /* The FMC module should be ready */
396         reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK);
397         if (!(reg & 0x80))
398                 dev_warn(dev, "FMC module not ready!\n");
399
400         /* Check which fans are enabled */
401         for (i = 0; i < 8; i++) {
402                 reg = pc87427_read8_bank(data, LD_FAN, BANK_FM(i),
403                                          PC87427_REG_FAN_STATUS);
404                 if (reg & FAN_STATUS_MONEN)
405                         data->fan_enabled |= (1 << i);
406         }
407
408         if (!data->fan_enabled) {
409                 dev_dbg(dev, "Enabling all fan inputs\n");
410                 for (i = 0; i < 8; i++)
411                         pc87427_write8_bank(data, LD_FAN, BANK_FM(i),
412                                             PC87427_REG_FAN_STATUS,
413                                             FAN_STATUS_MONEN);
414                 data->fan_enabled = 0xff;
415         }
416 }
417
418 static int __devinit pc87427_probe(struct platform_device *pdev)
419 {
420         struct pc87427_data *data;
421         struct resource *res;
422         int i, err;
423
424         if (!(data = kzalloc(sizeof(struct pc87427_data), GFP_KERNEL))) {
425                 err = -ENOMEM;
426                 printk(KERN_ERR DRVNAME ": Out of memory\n");
427                 goto exit;
428         }
429
430         /* This will need to be revisited when we add support for
431            temperature and voltage monitoring. */
432         res = platform_get_resource(pdev, IORESOURCE_IO, 0);
433         if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
434                 err = -EBUSY;
435                 dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
436                         (unsigned long)res->start, (unsigned long)res->end);
437                 goto exit_kfree;
438         }
439         data->address[0] = res->start;
440
441         mutex_init(&data->lock);
442         data->name = "pc87427";
443         platform_set_drvdata(pdev, data);
444         pc87427_init_device(&pdev->dev);
445
446         /* Register sysfs hooks */
447         if ((err = device_create_file(&pdev->dev, &dev_attr_name)))
448                 goto exit_release_region;
449         for (i = 0; i < 8; i++) {
450                 if (!(data->fan_enabled & (1 << i)))
451                         continue;
452                 if ((err = sysfs_create_group(&pdev->dev.kobj,
453                                               &pc87427_group_fan[i])))
454                         goto exit_remove_files;
455         }
456
457         data->class_dev = hwmon_device_register(&pdev->dev);
458         if (IS_ERR(data->class_dev)) {
459                 err = PTR_ERR(data->class_dev);
460                 dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
461                 goto exit_remove_files;
462         }
463
464         return 0;
465
466 exit_remove_files:
467         for (i = 0; i < 8; i++) {
468                 if (!(data->fan_enabled & (1 << i)))
469                         continue;
470                 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
471         }
472 exit_release_region:
473         release_region(res->start, res->end - res->start + 1);
474 exit_kfree:
475         platform_set_drvdata(pdev, NULL);
476         kfree(data);
477 exit:
478         return err;
479 }
480
481 static int __devexit pc87427_remove(struct platform_device *pdev)
482 {
483         struct pc87427_data *data = platform_get_drvdata(pdev);
484         struct resource *res;
485         int i;
486
487         hwmon_device_unregister(data->class_dev);
488         device_remove_file(&pdev->dev, &dev_attr_name);
489         for (i = 0; i < 8; i++) {
490                 if (!(data->fan_enabled & (1 << i)))
491                         continue;
492                 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
493         }
494         platform_set_drvdata(pdev, NULL);
495         kfree(data);
496
497         res = platform_get_resource(pdev, IORESOURCE_IO, 0);
498         release_region(res->start, res->end - res->start + 1);
499
500         return 0;
501 }
502
503
504 static struct platform_driver pc87427_driver = {
505         .driver = {
506                 .owner  = THIS_MODULE,
507                 .name   = DRVNAME,
508         },
509         .probe          = pc87427_probe,
510         .remove         = __devexit_p(pc87427_remove),
511 };
512
513 static int __init pc87427_device_add(unsigned short address)
514 {
515         struct resource res = {
516                 .start  = address,
517                 .end    = address + REGION_LENGTH - 1,
518                 .name   = logdev_str[0],
519                 .flags  = IORESOURCE_IO,
520         };
521         int err;
522
523         pdev = platform_device_alloc(DRVNAME, address);
524         if (!pdev) {
525                 err = -ENOMEM;
526                 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
527                 goto exit;
528         }
529
530         err = platform_device_add_resources(pdev, &res, 1);
531         if (err) {
532                 printk(KERN_ERR DRVNAME ": Device resource addition failed "
533                        "(%d)\n", err);
534                 goto exit_device_put;
535         }
536
537         err = platform_device_add(pdev);
538         if (err) {
539                 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
540                        err);
541                 goto exit_device_put;
542         }
543
544         return 0;
545
546 exit_device_put:
547         platform_device_put(pdev);
548 exit:
549         return err;
550 }
551
552 static int __init pc87427_find(int sioaddr, unsigned short *address)
553 {
554         u16 val;
555         int i, err = 0;
556
557         /* Identify device */
558         val = superio_inb(sioaddr, SIOREG_DEVID);
559         if (val != 0xf2) {      /* PC87427 */
560                 err = -ENODEV;
561                 goto exit;
562         }
563
564         for (i = 0; i < 2; i++) {
565                 address[i] = 0;
566                 /* Select logical device */
567                 superio_outb(sioaddr, SIOREG_LDSEL, logdev[i]);
568
569                 val = superio_inb(sioaddr, SIOREG_ACT);
570                 if (!(val & 0x01)) {
571                         printk(KERN_INFO DRVNAME ": Logical device 0x%02x "
572                                "not activated\n", logdev[i]);
573                         continue;
574                 }
575
576                 val = superio_inb(sioaddr, SIOREG_MAP);
577                 if (val & 0x01) {
578                         printk(KERN_WARNING DRVNAME ": Logical device 0x%02x "
579                                "is memory-mapped, can't use\n", logdev[i]);
580                         continue;
581                 }
582
583                 val = (superio_inb(sioaddr, SIOREG_IOBASE) << 8)
584                     | superio_inb(sioaddr, SIOREG_IOBASE + 1);
585                 if (!val) {
586                         printk(KERN_INFO DRVNAME ": I/O base address not set "
587                                "for logical device 0x%02x\n", logdev[i]);
588                         continue;
589                 }
590                 address[i] = val;
591         }
592
593 exit:
594         superio_exit(sioaddr);
595         return err;
596 }
597
598 static int __init pc87427_init(void)
599 {
600         int err;
601         unsigned short address[2];
602
603         if (pc87427_find(0x2e, address)
604          && pc87427_find(0x4e, address))
605                 return -ENODEV;
606
607         /* For now the driver only handles fans so we only care about the
608            first address. */
609         if (!address[0])
610                 return -ENODEV;
611
612         err = platform_driver_register(&pc87427_driver);
613         if (err)
614                 goto exit;
615
616         /* Sets global pdev as a side effect */
617         err = pc87427_device_add(address[0]);
618         if (err)
619                 goto exit_driver;
620
621         return 0;
622
623 exit_driver:
624         platform_driver_unregister(&pc87427_driver);
625 exit:
626         return err;
627 }
628
629 static void __exit pc87427_exit(void)
630 {
631         platform_device_unregister(pdev);
632         platform_driver_unregister(&pc87427_driver);
633 }
634
635 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
636 MODULE_DESCRIPTION("PC87427 hardware monitoring driver");
637 MODULE_LICENSE("GPL");
638
639 module_init(pc87427_init);
640 module_exit(pc87427_exit);