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