diff options
Diffstat (limited to 'drivers/hwmon/via686a.c')
-rw-r--r-- | drivers/hwmon/via686a.c | 538 |
1 files changed, 268 insertions, 270 deletions
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index 9a440c8cc520..24a6851491d0 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -34,9 +34,9 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/jiffies.h> | 36 | #include <linux/jiffies.h> |
37 | #include <linux/i2c.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/i2c-isa.h> | ||
39 | #include <linux/hwmon.h> | 38 | #include <linux/hwmon.h> |
39 | #include <linux/hwmon-sysfs.h> | ||
40 | #include <linux/err.h> | 40 | #include <linux/err.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
@@ -51,10 +51,7 @@ module_param(force_addr, ushort, 0); | |||
51 | MODULE_PARM_DESC(force_addr, | 51 | MODULE_PARM_DESC(force_addr, |
52 | "Initialize the base address of the sensors"); | 52 | "Initialize the base address of the sensors"); |
53 | 53 | ||
54 | /* Device address | 54 | static struct platform_device *pdev; |
55 | Note that we can't determine the ISA address until we have initialized | ||
56 | our module */ | ||
57 | static unsigned short address; | ||
58 | 55 | ||
59 | /* | 56 | /* |
60 | The Via 686a southbridge has a LM78-like chip integrated on the same IC. | 57 | The Via 686a southbridge has a LM78-like chip integrated on the same IC. |
@@ -295,7 +292,8 @@ static inline long TEMP_FROM_REG10(u16 val) | |||
295 | /* For each registered chip, we need to keep some data in memory. | 292 | /* For each registered chip, we need to keep some data in memory. |
296 | The structure is dynamically allocated. */ | 293 | The structure is dynamically allocated. */ |
297 | struct via686a_data { | 294 | struct via686a_data { |
298 | struct i2c_client client; | 295 | unsigned short addr; |
296 | const char *name; | ||
299 | struct class_device *class_dev; | 297 | struct class_device *class_dev; |
300 | struct mutex update_lock; | 298 | struct mutex update_lock; |
301 | char valid; /* !=0 if following fields are valid */ | 299 | char valid; /* !=0 if following fields are valid */ |
@@ -315,98 +313,85 @@ struct via686a_data { | |||
315 | 313 | ||
316 | static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ | 314 | static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ |
317 | 315 | ||
318 | static int via686a_detect(struct i2c_adapter *adapter); | 316 | static int via686a_probe(struct platform_device *pdev); |
319 | static int via686a_detach_client(struct i2c_client *client); | 317 | static int via686a_remove(struct platform_device *pdev); |
320 | 318 | ||
321 | static inline int via686a_read_value(struct i2c_client *client, u8 reg) | 319 | static inline int via686a_read_value(struct via686a_data *data, u8 reg) |
322 | { | 320 | { |
323 | return (inb_p(client->addr + reg)); | 321 | return inb_p(data->addr + reg); |
324 | } | 322 | } |
325 | 323 | ||
326 | static inline void via686a_write_value(struct i2c_client *client, u8 reg, | 324 | static inline void via686a_write_value(struct via686a_data *data, u8 reg, |
327 | u8 value) | 325 | u8 value) |
328 | { | 326 | { |
329 | outb_p(value, client->addr + reg); | 327 | outb_p(value, data->addr + reg); |
330 | } | 328 | } |
331 | 329 | ||
332 | static struct via686a_data *via686a_update_device(struct device *dev); | 330 | static struct via686a_data *via686a_update_device(struct device *dev); |
333 | static void via686a_init_client(struct i2c_client *client); | 331 | static void via686a_init_device(struct via686a_data *data); |
334 | 332 | ||
335 | /* following are the sysfs callback functions */ | 333 | /* following are the sysfs callback functions */ |
336 | 334 | ||
337 | /* 7 voltage sensors */ | 335 | /* 7 voltage sensors */ |
338 | static ssize_t show_in(struct device *dev, char *buf, int nr) { | 336 | static ssize_t show_in(struct device *dev, struct device_attribute *da, |
337 | char *buf) { | ||
339 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
340 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)); | 341 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)); |
341 | } | 342 | } |
342 | 343 | ||
343 | static ssize_t show_in_min(struct device *dev, char *buf, int nr) { | 344 | static ssize_t show_in_min(struct device *dev, struct device_attribute *da, |
345 | char *buf) { | ||
344 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
345 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)); | 349 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)); |
346 | } | 350 | } |
347 | 351 | ||
348 | static ssize_t show_in_max(struct device *dev, char *buf, int nr) { | 352 | static ssize_t show_in_max(struct device *dev, struct device_attribute *da, |
353 | char *buf) { | ||
349 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
350 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)); | 357 | return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)); |
351 | } | 358 | } |
352 | 359 | ||
353 | static ssize_t set_in_min(struct device *dev, const char *buf, | 360 | static ssize_t set_in_min(struct device *dev, struct device_attribute *da, |
354 | size_t count, int nr) { | 361 | const char *buf, size_t count) { |
355 | struct i2c_client *client = to_i2c_client(dev); | 362 | struct via686a_data *data = dev_get_drvdata(dev); |
356 | struct via686a_data *data = i2c_get_clientdata(client); | 363 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
364 | int nr = attr->index; | ||
357 | unsigned long val = simple_strtoul(buf, NULL, 10); | 365 | unsigned long val = simple_strtoul(buf, NULL, 10); |
358 | 366 | ||
359 | mutex_lock(&data->update_lock); | 367 | mutex_lock(&data->update_lock); |
360 | data->in_min[nr] = IN_TO_REG(val, nr); | 368 | data->in_min[nr] = IN_TO_REG(val, nr); |
361 | via686a_write_value(client, VIA686A_REG_IN_MIN(nr), | 369 | via686a_write_value(data, VIA686A_REG_IN_MIN(nr), |
362 | data->in_min[nr]); | 370 | data->in_min[nr]); |
363 | mutex_unlock(&data->update_lock); | 371 | mutex_unlock(&data->update_lock); |
364 | return count; | 372 | return count; |
365 | } | 373 | } |
366 | static ssize_t set_in_max(struct device *dev, const char *buf, | 374 | static ssize_t set_in_max(struct device *dev, struct device_attribute *da, |
367 | size_t count, int nr) { | 375 | const char *buf, size_t count) { |
368 | struct i2c_client *client = to_i2c_client(dev); | 376 | struct via686a_data *data = dev_get_drvdata(dev); |
369 | struct via686a_data *data = i2c_get_clientdata(client); | 377 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
378 | int nr = attr->index; | ||
370 | unsigned long val = simple_strtoul(buf, NULL, 10); | 379 | unsigned long val = simple_strtoul(buf, NULL, 10); |
371 | 380 | ||
372 | mutex_lock(&data->update_lock); | 381 | mutex_lock(&data->update_lock); |
373 | data->in_max[nr] = IN_TO_REG(val, nr); | 382 | data->in_max[nr] = IN_TO_REG(val, nr); |
374 | via686a_write_value(client, VIA686A_REG_IN_MAX(nr), | 383 | via686a_write_value(data, VIA686A_REG_IN_MAX(nr), |
375 | data->in_max[nr]); | 384 | data->in_max[nr]); |
376 | mutex_unlock(&data->update_lock); | 385 | mutex_unlock(&data->update_lock); |
377 | return count; | 386 | return count; |
378 | } | 387 | } |
379 | #define show_in_offset(offset) \ | 388 | #define show_in_offset(offset) \ |
380 | static ssize_t \ | 389 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ |
381 | show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 390 | show_in, NULL, offset); \ |
382 | { \ | 391 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ |
383 | return show_in(dev, buf, offset); \ | 392 | show_in_min, set_in_min, offset); \ |
384 | } \ | 393 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ |
385 | static ssize_t \ | 394 | show_in_max, set_in_max, offset); |
386 | show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
387 | { \ | ||
388 | return show_in_min(dev, buf, offset); \ | ||
389 | } \ | ||
390 | static ssize_t \ | ||
391 | show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
392 | { \ | ||
393 | return show_in_max(dev, buf, offset); \ | ||
394 | } \ | ||
395 | static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
396 | const char *buf, size_t count) \ | ||
397 | { \ | ||
398 | return set_in_min(dev, buf, count, offset); \ | ||
399 | } \ | ||
400 | static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \ | ||
401 | const char *buf, size_t count) \ | ||
402 | { \ | ||
403 | return set_in_max(dev, buf, count, offset); \ | ||
404 | } \ | ||
405 | static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\ | ||
406 | static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
407 | show_in##offset##_min, set_in##offset##_min); \ | ||
408 | static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
409 | show_in##offset##_max, set_in##offset##_max); | ||
410 | 395 | ||
411 | show_in_offset(0); | 396 | show_in_offset(0); |
412 | show_in_offset(1); | 397 | show_in_offset(1); |
@@ -415,150 +400,128 @@ show_in_offset(3); | |||
415 | show_in_offset(4); | 400 | show_in_offset(4); |
416 | 401 | ||
417 | /* 3 temperatures */ | 402 | /* 3 temperatures */ |
418 | static ssize_t show_temp(struct device *dev, char *buf, int nr) { | 403 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, |
404 | char *buf) { | ||
419 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
420 | return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])); | 408 | return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])); |
421 | } | 409 | } |
422 | static ssize_t show_temp_over(struct device *dev, char *buf, int nr) { | 410 | static ssize_t show_temp_over(struct device *dev, struct device_attribute *da, |
411 | char *buf) { | ||
423 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
424 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])); | 415 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])); |
425 | } | 416 | } |
426 | static ssize_t show_temp_hyst(struct device *dev, char *buf, int nr) { | 417 | static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da, |
418 | char *buf) { | ||
427 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
428 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])); | 422 | return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])); |
429 | } | 423 | } |
430 | static ssize_t set_temp_over(struct device *dev, const char *buf, | 424 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *da, |
431 | size_t count, int nr) { | 425 | const char *buf, size_t count) { |
432 | struct i2c_client *client = to_i2c_client(dev); | 426 | struct via686a_data *data = dev_get_drvdata(dev); |
433 | struct via686a_data *data = i2c_get_clientdata(client); | 427 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
428 | int nr = attr->index; | ||
434 | int val = simple_strtol(buf, NULL, 10); | 429 | int val = simple_strtol(buf, NULL, 10); |
435 | 430 | ||
436 | mutex_lock(&data->update_lock); | 431 | mutex_lock(&data->update_lock); |
437 | data->temp_over[nr] = TEMP_TO_REG(val); | 432 | data->temp_over[nr] = TEMP_TO_REG(val); |
438 | via686a_write_value(client, VIA686A_REG_TEMP_OVER[nr], | 433 | via686a_write_value(data, VIA686A_REG_TEMP_OVER[nr], |
439 | data->temp_over[nr]); | 434 | data->temp_over[nr]); |
440 | mutex_unlock(&data->update_lock); | 435 | mutex_unlock(&data->update_lock); |
441 | return count; | 436 | return count; |
442 | } | 437 | } |
443 | static ssize_t set_temp_hyst(struct device *dev, const char *buf, | 438 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da, |
444 | size_t count, int nr) { | 439 | const char *buf, size_t count) { |
445 | struct i2c_client *client = to_i2c_client(dev); | 440 | struct via686a_data *data = dev_get_drvdata(dev); |
446 | struct via686a_data *data = i2c_get_clientdata(client); | 441 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
442 | int nr = attr->index; | ||
447 | int val = simple_strtol(buf, NULL, 10); | 443 | int val = simple_strtol(buf, NULL, 10); |
448 | 444 | ||
449 | mutex_lock(&data->update_lock); | 445 | mutex_lock(&data->update_lock); |
450 | data->temp_hyst[nr] = TEMP_TO_REG(val); | 446 | data->temp_hyst[nr] = TEMP_TO_REG(val); |
451 | via686a_write_value(client, VIA686A_REG_TEMP_HYST[nr], | 447 | via686a_write_value(data, VIA686A_REG_TEMP_HYST[nr], |
452 | data->temp_hyst[nr]); | 448 | data->temp_hyst[nr]); |
453 | mutex_unlock(&data->update_lock); | 449 | mutex_unlock(&data->update_lock); |
454 | return count; | 450 | return count; |
455 | } | 451 | } |
456 | #define show_temp_offset(offset) \ | 452 | #define show_temp_offset(offset) \ |
457 | static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 453 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
458 | { \ | 454 | show_temp, NULL, offset - 1); \ |
459 | return show_temp(dev, buf, offset - 1); \ | 455 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ |
460 | } \ | 456 | show_temp_over, set_temp_over, offset - 1); \ |
461 | static ssize_t \ | 457 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ |
462 | show_temp_##offset##_over (struct device *dev, struct device_attribute *attr, char *buf) \ | 458 | show_temp_hyst, set_temp_hyst, offset - 1); |
463 | { \ | ||
464 | return show_temp_over(dev, buf, offset - 1); \ | ||
465 | } \ | ||
466 | static ssize_t \ | ||
467 | show_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
468 | { \ | ||
469 | return show_temp_hyst(dev, buf, offset - 1); \ | ||
470 | } \ | ||
471 | static ssize_t set_temp_##offset##_over (struct device *dev, struct device_attribute *attr, \ | ||
472 | const char *buf, size_t count) \ | ||
473 | { \ | ||
474 | return set_temp_over(dev, buf, count, offset - 1); \ | ||
475 | } \ | ||
476 | static ssize_t set_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, \ | ||
477 | const char *buf, size_t count) \ | ||
478 | { \ | ||
479 | return set_temp_hyst(dev, buf, count, offset - 1); \ | ||
480 | } \ | ||
481 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\ | ||
482 | static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
483 | show_temp_##offset##_over, set_temp_##offset##_over); \ | ||
484 | static DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ | ||
485 | show_temp_##offset##_hyst, set_temp_##offset##_hyst); | ||
486 | 459 | ||
487 | show_temp_offset(1); | 460 | show_temp_offset(1); |
488 | show_temp_offset(2); | 461 | show_temp_offset(2); |
489 | show_temp_offset(3); | 462 | show_temp_offset(3); |
490 | 463 | ||
491 | /* 2 Fans */ | 464 | /* 2 Fans */ |
492 | static ssize_t show_fan(struct device *dev, char *buf, int nr) { | 465 | static ssize_t show_fan(struct device *dev, struct device_attribute *da, |
466 | char *buf) { | ||
493 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
494 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], | 470 | return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], |
495 | DIV_FROM_REG(data->fan_div[nr])) ); | 471 | DIV_FROM_REG(data->fan_div[nr])) ); |
496 | } | 472 | } |
497 | static ssize_t show_fan_min(struct device *dev, char *buf, int nr) { | 473 | static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, |
474 | char *buf) { | ||
498 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
499 | return sprintf(buf, "%d\n", | 478 | return sprintf(buf, "%d\n", |
500 | FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) ); | 479 | FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) ); |
501 | } | 480 | } |
502 | static ssize_t show_fan_div(struct device *dev, char *buf, int nr) { | 481 | static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, |
482 | char *buf) { | ||
503 | struct via686a_data *data = via686a_update_device(dev); | 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; | ||
504 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); | 486 | return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); |
505 | } | 487 | } |
506 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 488 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, |
507 | size_t count, int nr) { | 489 | const char *buf, size_t count) { |
508 | struct i2c_client *client = to_i2c_client(dev); | 490 | struct via686a_data *data = dev_get_drvdata(dev); |
509 | struct via686a_data *data = i2c_get_clientdata(client); | 491 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
492 | int nr = attr->index; | ||
510 | int val = simple_strtol(buf, NULL, 10); | 493 | int val = simple_strtol(buf, NULL, 10); |
511 | 494 | ||
512 | mutex_lock(&data->update_lock); | 495 | mutex_lock(&data->update_lock); |
513 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 496 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
514 | via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); | 497 | via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); |
515 | mutex_unlock(&data->update_lock); | 498 | mutex_unlock(&data->update_lock); |
516 | return count; | 499 | return count; |
517 | } | 500 | } |
518 | static ssize_t set_fan_div(struct device *dev, const char *buf, | 501 | static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, |
519 | size_t count, int nr) { | 502 | const char *buf, size_t count) { |
520 | struct i2c_client *client = to_i2c_client(dev); | 503 | struct via686a_data *data = dev_get_drvdata(dev); |
521 | struct via686a_data *data = i2c_get_clientdata(client); | 504 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
505 | int nr = attr->index; | ||
522 | int val = simple_strtol(buf, NULL, 10); | 506 | int val = simple_strtol(buf, NULL, 10); |
523 | int old; | 507 | int old; |
524 | 508 | ||
525 | mutex_lock(&data->update_lock); | 509 | mutex_lock(&data->update_lock); |
526 | old = via686a_read_value(client, VIA686A_REG_FANDIV); | 510 | old = via686a_read_value(data, VIA686A_REG_FANDIV); |
527 | data->fan_div[nr] = DIV_TO_REG(val); | 511 | data->fan_div[nr] = DIV_TO_REG(val); |
528 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); | 512 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); |
529 | via686a_write_value(client, VIA686A_REG_FANDIV, old); | 513 | via686a_write_value(data, VIA686A_REG_FANDIV, old); |
530 | mutex_unlock(&data->update_lock); | 514 | mutex_unlock(&data->update_lock); |
531 | return count; | 515 | return count; |
532 | } | 516 | } |
533 | 517 | ||
534 | #define show_fan_offset(offset) \ | 518 | #define show_fan_offset(offset) \ |
535 | static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ | 519 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
536 | { \ | 520 | show_fan, NULL, offset - 1); \ |
537 | return show_fan(dev, buf, offset - 1); \ | 521 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ |
538 | } \ | 522 | show_fan_min, set_fan_min, offset - 1); \ |
539 | static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ | 523 | static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ |
540 | { \ | 524 | show_fan_div, set_fan_div, offset - 1); |
541 | return show_fan_min(dev, buf, offset - 1); \ | ||
542 | } \ | ||
543 | static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ | ||
544 | { \ | ||
545 | return show_fan_div(dev, buf, offset - 1); \ | ||
546 | } \ | ||
547 | static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ | ||
548 | const char *buf, size_t count) \ | ||
549 | { \ | ||
550 | return set_fan_min(dev, buf, count, offset - 1); \ | ||
551 | } \ | ||
552 | static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr, \ | ||
553 | const char *buf, size_t count) \ | ||
554 | { \ | ||
555 | return set_fan_div(dev, buf, count, offset - 1); \ | ||
556 | } \ | ||
557 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ | ||
558 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
559 | show_fan_##offset##_min, set_fan_##offset##_min); \ | ||
560 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ | ||
561 | show_fan_##offset##_div, set_fan_##offset##_div); | ||
562 | 525 | ||
563 | show_fan_offset(1); | 526 | show_fan_offset(1); |
564 | show_fan_offset(2); | 527 | show_fan_offset(2); |
@@ -570,41 +533,50 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch | |||
570 | } | 533 | } |
571 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 534 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
572 | 535 | ||
536 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
537 | *devattr, char *buf) | ||
538 | { | ||
539 | struct via686a_data *data = dev_get_drvdata(dev); | ||
540 | return sprintf(buf, "%s\n", data->name); | ||
541 | } | ||
542 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
543 | |||
573 | static struct attribute *via686a_attributes[] = { | 544 | static struct attribute *via686a_attributes[] = { |
574 | &dev_attr_in0_input.attr, | 545 | &sensor_dev_attr_in0_input.dev_attr.attr, |
575 | &dev_attr_in1_input.attr, | 546 | &sensor_dev_attr_in1_input.dev_attr.attr, |
576 | &dev_attr_in2_input.attr, | 547 | &sensor_dev_attr_in2_input.dev_attr.attr, |
577 | &dev_attr_in3_input.attr, | 548 | &sensor_dev_attr_in3_input.dev_attr.attr, |
578 | &dev_attr_in4_input.attr, | 549 | &sensor_dev_attr_in4_input.dev_attr.attr, |
579 | &dev_attr_in0_min.attr, | 550 | &sensor_dev_attr_in0_min.dev_attr.attr, |
580 | &dev_attr_in1_min.attr, | 551 | &sensor_dev_attr_in1_min.dev_attr.attr, |
581 | &dev_attr_in2_min.attr, | 552 | &sensor_dev_attr_in2_min.dev_attr.attr, |
582 | &dev_attr_in3_min.attr, | 553 | &sensor_dev_attr_in3_min.dev_attr.attr, |
583 | &dev_attr_in4_min.attr, | 554 | &sensor_dev_attr_in4_min.dev_attr.attr, |
584 | &dev_attr_in0_max.attr, | 555 | &sensor_dev_attr_in0_max.dev_attr.attr, |
585 | &dev_attr_in1_max.attr, | 556 | &sensor_dev_attr_in1_max.dev_attr.attr, |
586 | &dev_attr_in2_max.attr, | 557 | &sensor_dev_attr_in2_max.dev_attr.attr, |
587 | &dev_attr_in3_max.attr, | 558 | &sensor_dev_attr_in3_max.dev_attr.attr, |
588 | &dev_attr_in4_max.attr, | 559 | &sensor_dev_attr_in4_max.dev_attr.attr, |
589 | 560 | ||
590 | &dev_attr_temp1_input.attr, | 561 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
591 | &dev_attr_temp2_input.attr, | 562 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
592 | &dev_attr_temp3_input.attr, | 563 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
593 | &dev_attr_temp1_max.attr, | 564 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
594 | &dev_attr_temp2_max.attr, | 565 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
595 | &dev_attr_temp3_max.attr, | 566 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
596 | &dev_attr_temp1_max_hyst.attr, | 567 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
597 | &dev_attr_temp2_max_hyst.attr, | 568 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, |
598 | &dev_attr_temp3_max_hyst.attr, | 569 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, |
599 | 570 | ||
600 | &dev_attr_fan1_input.attr, | 571 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
601 | &dev_attr_fan2_input.attr, | 572 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
602 | &dev_attr_fan1_min.attr, | 573 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
603 | &dev_attr_fan2_min.attr, | 574 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
604 | &dev_attr_fan1_div.attr, | 575 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
605 | &dev_attr_fan2_div.attr, | 576 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
606 | 577 | ||
607 | &dev_attr_alarms.attr, | 578 | &dev_attr_alarms.attr, |
579 | &dev_attr_name.attr, | ||
608 | NULL | 580 | NULL |
609 | }; | 581 | }; |
610 | 582 | ||
@@ -612,58 +584,29 @@ static const struct attribute_group via686a_group = { | |||
612 | .attrs = via686a_attributes, | 584 | .attrs = via686a_attributes, |
613 | }; | 585 | }; |
614 | 586 | ||
615 | /* The driver. I choose to use type i2c_driver, as at is identical to both | 587 | static struct platform_driver via686a_driver = { |
616 | smbus_driver and isa_driver, and clients could be of either kind */ | ||
617 | static struct i2c_driver via686a_driver = { | ||
618 | .driver = { | 588 | .driver = { |
619 | .owner = THIS_MODULE, | 589 | .owner = THIS_MODULE, |
620 | .name = "via686a", | 590 | .name = "via686a", |
621 | }, | 591 | }, |
622 | .attach_adapter = via686a_detect, | 592 | .probe = via686a_probe, |
623 | .detach_client = via686a_detach_client, | 593 | .remove = __devexit_p(via686a_remove), |
624 | }; | 594 | }; |
625 | 595 | ||
626 | 596 | ||
627 | /* This is called when the module is loaded */ | 597 | /* This is called when the module is loaded */ |
628 | static int via686a_detect(struct i2c_adapter *adapter) | 598 | static int __devinit via686a_probe(struct platform_device *pdev) |
629 | { | 599 | { |
630 | struct i2c_client *new_client; | ||
631 | struct via686a_data *data; | 600 | struct via686a_data *data; |
632 | int err = 0; | 601 | struct resource *res; |
633 | const char client_name[] = "via686a"; | 602 | int err; |
634 | u16 val; | ||
635 | |||
636 | /* 8231 requires multiple of 256, we enforce that on 686 as well */ | ||
637 | if (force_addr) { | ||
638 | address = force_addr & 0xFF00; | ||
639 | dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", | ||
640 | address); | ||
641 | if (PCIBIOS_SUCCESSFUL != | ||
642 | pci_write_config_word(s_bridge, VIA686A_BASE_REG, address)) | ||
643 | return -ENODEV; | ||
644 | } | ||
645 | if (PCIBIOS_SUCCESSFUL != | ||
646 | pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val)) | ||
647 | return -ENODEV; | ||
648 | if (!(val & 0x0001)) { | ||
649 | if (force_addr) { | ||
650 | dev_info(&adapter->dev, "enabling sensors\n"); | ||
651 | if (PCIBIOS_SUCCESSFUL != | ||
652 | pci_write_config_word(s_bridge, VIA686A_ENABLE_REG, | ||
653 | val | 0x0001)) | ||
654 | return -ENODEV; | ||
655 | } else { | ||
656 | dev_warn(&adapter->dev, "sensors disabled - enable " | ||
657 | "with force_addr=0x%x\n", address); | ||
658 | return -ENODEV; | ||
659 | } | ||
660 | } | ||
661 | 603 | ||
662 | /* Reserve the ISA region */ | 604 | /* Reserve the ISA region */ |
663 | if (!request_region(address, VIA686A_EXTENT, | 605 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
606 | if (!request_region(res->start, VIA686A_EXTENT, | ||
664 | via686a_driver.driver.name)) { | 607 | via686a_driver.driver.name)) { |
665 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | 608 | dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n", |
666 | address); | 609 | (unsigned long)res->start, (unsigned long)res->end); |
667 | return -ENODEV; | 610 | return -ENODEV; |
668 | } | 611 | } |
669 | 612 | ||
@@ -672,30 +615,19 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
672 | goto exit_release; | 615 | goto exit_release; |
673 | } | 616 | } |
674 | 617 | ||
675 | new_client = &data->client; | 618 | platform_set_drvdata(pdev, data); |
676 | i2c_set_clientdata(new_client, data); | 619 | data->addr = res->start; |
677 | new_client->addr = address; | 620 | data->name = "via686a"; |
678 | new_client->adapter = adapter; | ||
679 | new_client->driver = &via686a_driver; | ||
680 | new_client->flags = 0; | ||
681 | |||
682 | /* Fill in the remaining client fields and put into the global list */ | ||
683 | strlcpy(new_client->name, client_name, I2C_NAME_SIZE); | ||
684 | |||
685 | data->valid = 0; | ||
686 | mutex_init(&data->update_lock); | 621 | mutex_init(&data->update_lock); |
687 | /* Tell the I2C layer a new client has arrived */ | ||
688 | if ((err = i2c_attach_client(new_client))) | ||
689 | goto exit_free; | ||
690 | 622 | ||
691 | /* Initialize the VIA686A chip */ | 623 | /* Initialize the VIA686A chip */ |
692 | via686a_init_client(new_client); | 624 | via686a_init_device(data); |
693 | 625 | ||
694 | /* Register sysfs hooks */ | 626 | /* Register sysfs hooks */ |
695 | if ((err = sysfs_create_group(&new_client->dev.kobj, &via686a_group))) | 627 | if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) |
696 | goto exit_detach; | 628 | goto exit_free; |
697 | 629 | ||
698 | data->class_dev = hwmon_device_register(&new_client->dev); | 630 | data->class_dev = hwmon_device_register(&pdev->dev); |
699 | if (IS_ERR(data->class_dev)) { | 631 | if (IS_ERR(data->class_dev)) { |
700 | err = PTR_ERR(data->class_dev); | 632 | err = PTR_ERR(data->class_dev); |
701 | goto exit_remove_files; | 633 | goto exit_remove_files; |
@@ -704,51 +636,46 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
704 | return 0; | 636 | return 0; |
705 | 637 | ||
706 | exit_remove_files: | 638 | exit_remove_files: |
707 | sysfs_remove_group(&new_client->dev.kobj, &via686a_group); | 639 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
708 | exit_detach: | ||
709 | i2c_detach_client(new_client); | ||
710 | exit_free: | 640 | exit_free: |
711 | kfree(data); | 641 | kfree(data); |
712 | exit_release: | 642 | exit_release: |
713 | release_region(address, VIA686A_EXTENT); | 643 | release_region(res->start, VIA686A_EXTENT); |
714 | return err; | 644 | return err; |
715 | } | 645 | } |
716 | 646 | ||
717 | static int via686a_detach_client(struct i2c_client *client) | 647 | static int __devexit via686a_remove(struct platform_device *pdev) |
718 | { | 648 | { |
719 | struct via686a_data *data = i2c_get_clientdata(client); | 649 | struct via686a_data *data = platform_get_drvdata(pdev); |
720 | int err; | ||
721 | 650 | ||
722 | hwmon_device_unregister(data->class_dev); | 651 | hwmon_device_unregister(data->class_dev); |
723 | sysfs_remove_group(&client->dev.kobj, &via686a_group); | 652 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
724 | 653 | ||
725 | if ((err = i2c_detach_client(client))) | 654 | release_region(data->addr, VIA686A_EXTENT); |
726 | return err; | 655 | platform_set_drvdata(pdev, NULL); |
727 | |||
728 | release_region(client->addr, VIA686A_EXTENT); | ||
729 | kfree(data); | 656 | kfree(data); |
730 | 657 | ||
731 | return 0; | 658 | return 0; |
732 | } | 659 | } |
733 | 660 | ||
734 | static void via686a_init_client(struct i2c_client *client) | 661 | static void __devinit via686a_init_device(struct via686a_data *data) |
735 | { | 662 | { |
736 | u8 reg; | 663 | u8 reg; |
737 | 664 | ||
738 | /* Start monitoring */ | 665 | /* Start monitoring */ |
739 | reg = via686a_read_value(client, VIA686A_REG_CONFIG); | 666 | reg = via686a_read_value(data, VIA686A_REG_CONFIG); |
740 | via686a_write_value(client, VIA686A_REG_CONFIG, (reg|0x01)&0x7F); | 667 | via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F); |
741 | 668 | ||
742 | /* Configure temp interrupt mode for continuous-interrupt operation */ | 669 | /* Configure temp interrupt mode for continuous-interrupt operation */ |
743 | via686a_write_value(client, VIA686A_REG_TEMP_MODE, | 670 | reg = via686a_read_value(data, VIA686A_REG_TEMP_MODE); |
744 | via686a_read_value(client, VIA686A_REG_TEMP_MODE) & | 671 | via686a_write_value(data, VIA686A_REG_TEMP_MODE, |
745 | !(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS)); | 672 | (reg & ~VIA686A_TEMP_MODE_MASK) |
673 | | VIA686A_TEMP_MODE_CONTINUOUS); | ||
746 | } | 674 | } |
747 | 675 | ||
748 | static struct via686a_data *via686a_update_device(struct device *dev) | 676 | static struct via686a_data *via686a_update_device(struct device *dev) |
749 | { | 677 | { |
750 | struct i2c_client *client = to_i2c_client(dev); | 678 | struct via686a_data *data = dev_get_drvdata(dev); |
751 | struct via686a_data *data = i2c_get_clientdata(client); | ||
752 | int i; | 679 | int i; |
753 | 680 | ||
754 | mutex_lock(&data->update_lock); | 681 | mutex_lock(&data->update_lock); |
@@ -757,27 +684,27 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
757 | || !data->valid) { | 684 | || !data->valid) { |
758 | for (i = 0; i <= 4; i++) { | 685 | for (i = 0; i <= 4; i++) { |
759 | data->in[i] = | 686 | data->in[i] = |
760 | via686a_read_value(client, VIA686A_REG_IN(i)); | 687 | via686a_read_value(data, VIA686A_REG_IN(i)); |
761 | data->in_min[i] = via686a_read_value(client, | 688 | data->in_min[i] = via686a_read_value(data, |
762 | VIA686A_REG_IN_MIN | 689 | VIA686A_REG_IN_MIN |
763 | (i)); | 690 | (i)); |
764 | data->in_max[i] = | 691 | data->in_max[i] = |
765 | via686a_read_value(client, VIA686A_REG_IN_MAX(i)); | 692 | via686a_read_value(data, VIA686A_REG_IN_MAX(i)); |
766 | } | 693 | } |
767 | for (i = 1; i <= 2; i++) { | 694 | for (i = 1; i <= 2; i++) { |
768 | data->fan[i - 1] = | 695 | data->fan[i - 1] = |
769 | via686a_read_value(client, VIA686A_REG_FAN(i)); | 696 | via686a_read_value(data, VIA686A_REG_FAN(i)); |
770 | data->fan_min[i - 1] = via686a_read_value(client, | 697 | data->fan_min[i - 1] = via686a_read_value(data, |
771 | VIA686A_REG_FAN_MIN(i)); | 698 | VIA686A_REG_FAN_MIN(i)); |
772 | } | 699 | } |
773 | for (i = 0; i <= 2; i++) { | 700 | for (i = 0; i <= 2; i++) { |
774 | data->temp[i] = via686a_read_value(client, | 701 | data->temp[i] = via686a_read_value(data, |
775 | VIA686A_REG_TEMP[i]) << 2; | 702 | VIA686A_REG_TEMP[i]) << 2; |
776 | data->temp_over[i] = | 703 | data->temp_over[i] = |
777 | via686a_read_value(client, | 704 | via686a_read_value(data, |
778 | VIA686A_REG_TEMP_OVER[i]); | 705 | VIA686A_REG_TEMP_OVER[i]); |
779 | data->temp_hyst[i] = | 706 | data->temp_hyst[i] = |
780 | via686a_read_value(client, | 707 | via686a_read_value(data, |
781 | VIA686A_REG_TEMP_HYST[i]); | 708 | VIA686A_REG_TEMP_HYST[i]); |
782 | } | 709 | } |
783 | /* add in lower 2 bits | 710 | /* add in lower 2 bits |
@@ -785,23 +712,23 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
785 | temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 | 712 | temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 |
786 | temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 | 713 | temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 |
787 | */ | 714 | */ |
788 | data->temp[0] |= (via686a_read_value(client, | 715 | data->temp[0] |= (via686a_read_value(data, |
789 | VIA686A_REG_TEMP_LOW1) | 716 | VIA686A_REG_TEMP_LOW1) |
790 | & 0xc0) >> 6; | 717 | & 0xc0) >> 6; |
791 | data->temp[1] |= | 718 | data->temp[1] |= |
792 | (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & | 719 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
793 | 0x30) >> 4; | 720 | 0x30) >> 4; |
794 | data->temp[2] |= | 721 | data->temp[2] |= |
795 | (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & | 722 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
796 | 0xc0) >> 6; | 723 | 0xc0) >> 6; |
797 | 724 | ||
798 | i = via686a_read_value(client, VIA686A_REG_FANDIV); | 725 | i = via686a_read_value(data, VIA686A_REG_FANDIV); |
799 | data->fan_div[0] = (i >> 4) & 0x03; | 726 | data->fan_div[0] = (i >> 4) & 0x03; |
800 | data->fan_div[1] = i >> 6; | 727 | data->fan_div[1] = i >> 6; |
801 | data->alarms = | 728 | data->alarms = |
802 | via686a_read_value(client, | 729 | via686a_read_value(data, |
803 | VIA686A_REG_ALARM1) | | 730 | VIA686A_REG_ALARM1) | |
804 | (via686a_read_value(client, VIA686A_REG_ALARM2) << 8); | 731 | (via686a_read_value(data, VIA686A_REG_ALARM2) << 8); |
805 | data->last_updated = jiffies; | 732 | data->last_updated = jiffies; |
806 | data->valid = 1; | 733 | data->valid = 1; |
807 | } | 734 | } |
@@ -818,32 +745,102 @@ static struct pci_device_id via686a_pci_ids[] = { | |||
818 | 745 | ||
819 | MODULE_DEVICE_TABLE(pci, via686a_pci_ids); | 746 | MODULE_DEVICE_TABLE(pci, via686a_pci_ids); |
820 | 747 | ||
748 | static int __devinit via686a_device_add(unsigned short address) | ||
749 | { | ||
750 | struct resource res = { | ||
751 | .start = address, | ||
752 | .end = address + VIA686A_EXTENT - 1, | ||
753 | .name = "via686a", | ||
754 | .flags = IORESOURCE_IO, | ||
755 | }; | ||
756 | int err; | ||
757 | |||
758 | pdev = platform_device_alloc("via686a", address); | ||
759 | if (!pdev) { | ||
760 | err = -ENOMEM; | ||
761 | printk(KERN_ERR "via686a: Device allocation failed\n"); | ||
762 | goto exit; | ||
763 | } | ||
764 | |||
765 | err = platform_device_add_resources(pdev, &res, 1); | ||
766 | if (err) { | ||
767 | printk(KERN_ERR "via686a: Device resource addition failed " | ||
768 | "(%d)\n", err); | ||
769 | goto exit_device_put; | ||
770 | } | ||
771 | |||
772 | err = platform_device_add(pdev); | ||
773 | if (err) { | ||
774 | printk(KERN_ERR "via686a: Device addition failed (%d)\n", | ||
775 | err); | ||
776 | goto exit_device_put; | ||
777 | } | ||
778 | |||
779 | return 0; | ||
780 | |||
781 | exit_device_put: | ||
782 | platform_device_put(pdev); | ||
783 | exit: | ||
784 | return err; | ||
785 | } | ||
786 | |||
821 | static int __devinit via686a_pci_probe(struct pci_dev *dev, | 787 | static int __devinit via686a_pci_probe(struct pci_dev *dev, |
822 | const struct pci_device_id *id) | 788 | const struct pci_device_id *id) |
823 | { | 789 | { |
824 | u16 val; | 790 | u16 address, val; |
825 | 791 | ||
792 | if (force_addr) { | ||
793 | address = force_addr & ~(VIA686A_EXTENT - 1); | ||
794 | dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address); | ||
795 | if (PCIBIOS_SUCCESSFUL != | ||
796 | pci_write_config_word(dev, VIA686A_BASE_REG, address | 1)) | ||
797 | return -ENODEV; | ||
798 | } | ||
826 | if (PCIBIOS_SUCCESSFUL != | 799 | if (PCIBIOS_SUCCESSFUL != |
827 | pci_read_config_word(dev, VIA686A_BASE_REG, &val)) | 800 | pci_read_config_word(dev, VIA686A_BASE_REG, &val)) |
828 | return -ENODEV; | 801 | return -ENODEV; |
829 | 802 | ||
830 | address = val & ~(VIA686A_EXTENT - 1); | 803 | address = val & ~(VIA686A_EXTENT - 1); |
831 | if (address == 0 && force_addr == 0) { | 804 | if (address == 0) { |
832 | dev_err(&dev->dev, "base address not set - upgrade BIOS " | 805 | dev_err(&dev->dev, "base address not set - upgrade BIOS " |
833 | "or use force_addr=0xaddr\n"); | 806 | "or use force_addr=0xaddr\n"); |
834 | return -ENODEV; | 807 | return -ENODEV; |
835 | } | 808 | } |
836 | 809 | ||
837 | s_bridge = pci_dev_get(dev); | 810 | if (PCIBIOS_SUCCESSFUL != |
838 | if (i2c_isa_add_driver(&via686a_driver)) { | 811 | pci_read_config_word(dev, VIA686A_ENABLE_REG, &val)) |
839 | pci_dev_put(s_bridge); | 812 | return -ENODEV; |
840 | s_bridge = NULL; | 813 | if (!(val & 0x0001)) { |
814 | if (!force_addr) { | ||
815 | dev_warn(&dev->dev, "Sensors disabled, enable " | ||
816 | "with force_addr=0x%x\n", address); | ||
817 | return -ENODEV; | ||
818 | } | ||
819 | |||
820 | dev_warn(&dev->dev, "Enabling sensors\n"); | ||
821 | if (PCIBIOS_SUCCESSFUL != | ||
822 | pci_write_config_word(dev, VIA686A_ENABLE_REG, | ||
823 | val | 0x0001)) | ||
824 | return -ENODEV; | ||
841 | } | 825 | } |
842 | 826 | ||
827 | if (platform_driver_register(&via686a_driver)) | ||
828 | goto exit; | ||
829 | |||
830 | /* Sets global pdev as a side effect */ | ||
831 | if (via686a_device_add(address)) | ||
832 | goto exit_unregister; | ||
833 | |||
843 | /* Always return failure here. This is to allow other drivers to bind | 834 | /* Always return failure here. This is to allow other drivers to bind |
844 | * to this pci device. We don't really want to have control over the | 835 | * to this pci device. We don't really want to have control over the |
845 | * pci device, we only wanted to read as few register values from it. | 836 | * pci device, we only wanted to read as few register values from it. |
846 | */ | 837 | */ |
838 | s_bridge = pci_dev_get(dev); | ||
839 | return -ENODEV; | ||
840 | |||
841 | exit_unregister: | ||
842 | platform_driver_unregister(&via686a_driver); | ||
843 | exit: | ||
847 | return -ENODEV; | 844 | return -ENODEV; |
848 | } | 845 | } |
849 | 846 | ||
@@ -862,7 +859,8 @@ static void __exit sm_via686a_exit(void) | |||
862 | { | 859 | { |
863 | pci_unregister_driver(&via686a_pci_driver); | 860 | pci_unregister_driver(&via686a_pci_driver); |
864 | if (s_bridge != NULL) { | 861 | if (s_bridge != NULL) { |
865 | i2c_isa_del_driver(&via686a_driver); | 862 | platform_device_unregister(pdev); |
863 | platform_driver_unregister(&via686a_driver); | ||
866 | pci_dev_put(s_bridge); | 864 | pci_dev_put(s_bridge); |
867 | s_bridge = NULL; | 865 | s_bridge = NULL; |
868 | } | 866 | } |