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