xref: /openbmc/linux/drivers/hwmon/pc87427.c (revision 64c70b1c)
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 	platform_set_drvdata(pdev, NULL);
488 	hwmon_device_unregister(data->class_dev);
489 	device_remove_file(&pdev->dev, &dev_attr_name);
490 	for (i = 0; i < 8; i++) {
491 		if (!(data->fan_enabled & (1 << i)))
492 			continue;
493 		sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
494 	}
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);
641