diff options
author | Jean Delvare <khali@linux-fr.org> | 2007-06-09 10:11:16 -0400 |
---|---|---|
committer | Mark M. Hoffman <mhoffman@lightlink.com> | 2007-07-19 14:22:13 -0400 |
commit | 2ec342e68453d9f3a1ac28ab80ffa8faacf58710 (patch) | |
tree | cb30c7109231f43d49f94401a0886c9f05f75941 /drivers/hwmon | |
parent | 58fe0809cc02d51b7aca05ee858c8bbb0af9e0b6 (diff) |
hwmon/via686a: Convert to a platform driver
Convert the via686a driver from the nonsensical i2c-isa hack to a
regular platform driver.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 3 | ||||
-rw-r--r-- | drivers/hwmon/via686a.c | 285 |
2 files changed, 156 insertions, 132 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 5868e1a1917a..b432584c49a8 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -497,8 +497,7 @@ config SENSORS_SMSC47B397 | |||
497 | 497 | ||
498 | config SENSORS_VIA686A | 498 | config SENSORS_VIA686A |
499 | tristate "VIA686A" | 499 | tristate "VIA686A" |
500 | depends on I2C && PCI | 500 | depends on PCI |
501 | select I2C_ISA | ||
502 | help | 501 | help |
503 | If you say yes here you get support for the integrated sensors in | 502 | If you say yes here you get support for the integrated sensors in |
504 | Via 686A/B South Bridges. | 503 | Via 686A/B South Bridges. |
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c index a25b0542649c..0ee9a278537a 100644 --- a/drivers/hwmon/via686a.c +++ b/drivers/hwmon/via686a.c | |||
@@ -34,8 +34,7 @@ | |||
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> |
40 | #include <linux/err.h> | 39 | #include <linux/err.h> |
41 | #include <linux/init.h> | 40 | #include <linux/init.h> |
@@ -51,10 +50,7 @@ module_param(force_addr, ushort, 0); | |||
51 | MODULE_PARM_DESC(force_addr, | 50 | MODULE_PARM_DESC(force_addr, |
52 | "Initialize the base address of the sensors"); | 51 | "Initialize the base address of the sensors"); |
53 | 52 | ||
54 | /* Device address | 53 | 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 | 54 | ||
59 | /* | 55 | /* |
60 | The Via 686a southbridge has a LM78-like chip integrated on the same IC. | 56 | The Via 686a southbridge has a LM78-like chip integrated on the same IC. |
@@ -295,7 +291,8 @@ static inline long TEMP_FROM_REG10(u16 val) | |||
295 | /* For each registered chip, we need to keep some data in memory. | 291 | /* For each registered chip, we need to keep some data in memory. |
296 | The structure is dynamically allocated. */ | 292 | The structure is dynamically allocated. */ |
297 | struct via686a_data { | 293 | struct via686a_data { |
298 | struct i2c_client client; | 294 | unsigned short addr; |
295 | const char *name; | ||
299 | struct class_device *class_dev; | 296 | struct class_device *class_dev; |
300 | struct mutex update_lock; | 297 | struct mutex update_lock; |
301 | char valid; /* !=0 if following fields are valid */ | 298 | char valid; /* !=0 if following fields are valid */ |
@@ -315,22 +312,22 @@ struct via686a_data { | |||
315 | 312 | ||
316 | static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ | 313 | static struct pci_dev *s_bridge; /* pointer to the (only) via686a */ |
317 | 314 | ||
318 | static int via686a_detect(struct i2c_adapter *adapter); | 315 | static int via686a_probe(struct platform_device *pdev); |
319 | static int via686a_detach_client(struct i2c_client *client); | 316 | static int via686a_remove(struct platform_device *pdev); |
320 | 317 | ||
321 | static inline int via686a_read_value(struct i2c_client *client, u8 reg) | 318 | static inline int via686a_read_value(struct via686a_data *data, u8 reg) |
322 | { | 319 | { |
323 | return (inb_p(client->addr + reg)); | 320 | return inb_p(data->addr + reg); |
324 | } | 321 | } |
325 | 322 | ||
326 | static inline void via686a_write_value(struct i2c_client *client, u8 reg, | 323 | static inline void via686a_write_value(struct via686a_data *data, u8 reg, |
327 | u8 value) | 324 | u8 value) |
328 | { | 325 | { |
329 | outb_p(value, client->addr + reg); | 326 | outb_p(value, data->addr + reg); |
330 | } | 327 | } |
331 | 328 | ||
332 | static struct via686a_data *via686a_update_device(struct device *dev); | 329 | static struct via686a_data *via686a_update_device(struct device *dev); |
333 | static void via686a_init_client(struct i2c_client *client); | 330 | static void via686a_init_device(struct via686a_data *data); |
334 | 331 | ||
335 | /* following are the sysfs callback functions */ | 332 | /* following are the sysfs callback functions */ |
336 | 333 | ||
@@ -352,26 +349,24 @@ static ssize_t show_in_max(struct device *dev, char *buf, int nr) { | |||
352 | 349 | ||
353 | static ssize_t set_in_min(struct device *dev, const char *buf, | 350 | static ssize_t set_in_min(struct device *dev, const char *buf, |
354 | size_t count, int nr) { | 351 | size_t count, int nr) { |
355 | struct i2c_client *client = to_i2c_client(dev); | 352 | struct via686a_data *data = dev_get_drvdata(dev); |
356 | struct via686a_data *data = i2c_get_clientdata(client); | ||
357 | unsigned long val = simple_strtoul(buf, NULL, 10); | 353 | unsigned long val = simple_strtoul(buf, NULL, 10); |
358 | 354 | ||
359 | mutex_lock(&data->update_lock); | 355 | mutex_lock(&data->update_lock); |
360 | data->in_min[nr] = IN_TO_REG(val, nr); | 356 | data->in_min[nr] = IN_TO_REG(val, nr); |
361 | via686a_write_value(client, VIA686A_REG_IN_MIN(nr), | 357 | via686a_write_value(data, VIA686A_REG_IN_MIN(nr), |
362 | data->in_min[nr]); | 358 | data->in_min[nr]); |
363 | mutex_unlock(&data->update_lock); | 359 | mutex_unlock(&data->update_lock); |
364 | return count; | 360 | return count; |
365 | } | 361 | } |
366 | static ssize_t set_in_max(struct device *dev, const char *buf, | 362 | static ssize_t set_in_max(struct device *dev, const char *buf, |
367 | size_t count, int nr) { | 363 | size_t count, int nr) { |
368 | struct i2c_client *client = to_i2c_client(dev); | 364 | struct via686a_data *data = dev_get_drvdata(dev); |
369 | struct via686a_data *data = i2c_get_clientdata(client); | ||
370 | unsigned long val = simple_strtoul(buf, NULL, 10); | 365 | unsigned long val = simple_strtoul(buf, NULL, 10); |
371 | 366 | ||
372 | mutex_lock(&data->update_lock); | 367 | mutex_lock(&data->update_lock); |
373 | data->in_max[nr] = IN_TO_REG(val, nr); | 368 | data->in_max[nr] = IN_TO_REG(val, nr); |
374 | via686a_write_value(client, VIA686A_REG_IN_MAX(nr), | 369 | via686a_write_value(data, VIA686A_REG_IN_MAX(nr), |
375 | data->in_max[nr]); | 370 | data->in_max[nr]); |
376 | mutex_unlock(&data->update_lock); | 371 | mutex_unlock(&data->update_lock); |
377 | return count; | 372 | return count; |
@@ -429,26 +424,24 @@ static ssize_t show_temp_hyst(struct device *dev, char *buf, int nr) { | |||
429 | } | 424 | } |
430 | static ssize_t set_temp_over(struct device *dev, const char *buf, | 425 | static ssize_t set_temp_over(struct device *dev, const char *buf, |
431 | size_t count, int nr) { | 426 | size_t count, int nr) { |
432 | struct i2c_client *client = to_i2c_client(dev); | 427 | struct via686a_data *data = dev_get_drvdata(dev); |
433 | struct via686a_data *data = i2c_get_clientdata(client); | ||
434 | int val = simple_strtol(buf, NULL, 10); | 428 | int val = simple_strtol(buf, NULL, 10); |
435 | 429 | ||
436 | mutex_lock(&data->update_lock); | 430 | mutex_lock(&data->update_lock); |
437 | data->temp_over[nr] = TEMP_TO_REG(val); | 431 | data->temp_over[nr] = TEMP_TO_REG(val); |
438 | via686a_write_value(client, VIA686A_REG_TEMP_OVER[nr], | 432 | via686a_write_value(data, VIA686A_REG_TEMP_OVER[nr], |
439 | data->temp_over[nr]); | 433 | data->temp_over[nr]); |
440 | mutex_unlock(&data->update_lock); | 434 | mutex_unlock(&data->update_lock); |
441 | return count; | 435 | return count; |
442 | } | 436 | } |
443 | static ssize_t set_temp_hyst(struct device *dev, const char *buf, | 437 | static ssize_t set_temp_hyst(struct device *dev, const char *buf, |
444 | size_t count, int nr) { | 438 | size_t count, int nr) { |
445 | struct i2c_client *client = to_i2c_client(dev); | 439 | struct via686a_data *data = dev_get_drvdata(dev); |
446 | struct via686a_data *data = i2c_get_clientdata(client); | ||
447 | int val = simple_strtol(buf, NULL, 10); | 440 | int val = simple_strtol(buf, NULL, 10); |
448 | 441 | ||
449 | mutex_lock(&data->update_lock); | 442 | mutex_lock(&data->update_lock); |
450 | data->temp_hyst[nr] = TEMP_TO_REG(val); | 443 | data->temp_hyst[nr] = TEMP_TO_REG(val); |
451 | via686a_write_value(client, VIA686A_REG_TEMP_HYST[nr], | 444 | via686a_write_value(data, VIA686A_REG_TEMP_HYST[nr], |
452 | data->temp_hyst[nr]); | 445 | data->temp_hyst[nr]); |
453 | mutex_unlock(&data->update_lock); | 446 | mutex_unlock(&data->update_lock); |
454 | return count; | 447 | return count; |
@@ -505,28 +498,26 @@ static ssize_t show_fan_div(struct device *dev, char *buf, int nr) { | |||
505 | } | 498 | } |
506 | static ssize_t set_fan_min(struct device *dev, const char *buf, | 499 | static ssize_t set_fan_min(struct device *dev, const char *buf, |
507 | size_t count, int nr) { | 500 | size_t count, int nr) { |
508 | struct i2c_client *client = to_i2c_client(dev); | 501 | struct via686a_data *data = dev_get_drvdata(dev); |
509 | struct via686a_data *data = i2c_get_clientdata(client); | ||
510 | int val = simple_strtol(buf, NULL, 10); | 502 | int val = simple_strtol(buf, NULL, 10); |
511 | 503 | ||
512 | mutex_lock(&data->update_lock); | 504 | mutex_lock(&data->update_lock); |
513 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 505 | 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]); | 506 | via686a_write_value(data, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]); |
515 | mutex_unlock(&data->update_lock); | 507 | mutex_unlock(&data->update_lock); |
516 | return count; | 508 | return count; |
517 | } | 509 | } |
518 | static ssize_t set_fan_div(struct device *dev, const char *buf, | 510 | static ssize_t set_fan_div(struct device *dev, const char *buf, |
519 | size_t count, int nr) { | 511 | size_t count, int nr) { |
520 | struct i2c_client *client = to_i2c_client(dev); | 512 | struct via686a_data *data = dev_get_drvdata(dev); |
521 | struct via686a_data *data = i2c_get_clientdata(client); | ||
522 | int val = simple_strtol(buf, NULL, 10); | 513 | int val = simple_strtol(buf, NULL, 10); |
523 | int old; | 514 | int old; |
524 | 515 | ||
525 | mutex_lock(&data->update_lock); | 516 | mutex_lock(&data->update_lock); |
526 | old = via686a_read_value(client, VIA686A_REG_FANDIV); | 517 | old = via686a_read_value(data, VIA686A_REG_FANDIV); |
527 | data->fan_div[nr] = DIV_TO_REG(val); | 518 | data->fan_div[nr] = DIV_TO_REG(val); |
528 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); | 519 | old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4); |
529 | via686a_write_value(client, VIA686A_REG_FANDIV, old); | 520 | via686a_write_value(data, VIA686A_REG_FANDIV, old); |
530 | mutex_unlock(&data->update_lock); | 521 | mutex_unlock(&data->update_lock); |
531 | return count; | 522 | return count; |
532 | } | 523 | } |
@@ -570,6 +561,14 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch | |||
570 | } | 561 | } |
571 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 562 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
572 | 563 | ||
564 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
565 | *devattr, char *buf) | ||
566 | { | ||
567 | struct via686a_data *data = dev_get_drvdata(dev); | ||
568 | return sprintf(buf, "%s\n", data->name); | ||
569 | } | ||
570 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
571 | |||
573 | static struct attribute *via686a_attributes[] = { | 572 | static struct attribute *via686a_attributes[] = { |
574 | &dev_attr_in0_input.attr, | 573 | &dev_attr_in0_input.attr, |
575 | &dev_attr_in1_input.attr, | 574 | &dev_attr_in1_input.attr, |
@@ -605,6 +604,7 @@ static struct attribute *via686a_attributes[] = { | |||
605 | &dev_attr_fan2_div.attr, | 604 | &dev_attr_fan2_div.attr, |
606 | 605 | ||
607 | &dev_attr_alarms.attr, | 606 | &dev_attr_alarms.attr, |
607 | &dev_attr_name.attr, | ||
608 | NULL | 608 | NULL |
609 | }; | 609 | }; |
610 | 610 | ||
@@ -612,58 +612,29 @@ static const struct attribute_group via686a_group = { | |||
612 | .attrs = via686a_attributes, | 612 | .attrs = via686a_attributes, |
613 | }; | 613 | }; |
614 | 614 | ||
615 | /* The driver. I choose to use type i2c_driver, as at is identical to both | 615 | 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 = { | 616 | .driver = { |
619 | .owner = THIS_MODULE, | 617 | .owner = THIS_MODULE, |
620 | .name = "via686a", | 618 | .name = "via686a", |
621 | }, | 619 | }, |
622 | .attach_adapter = via686a_detect, | 620 | .probe = via686a_probe, |
623 | .detach_client = via686a_detach_client, | 621 | .remove = __devexit_p(via686a_remove), |
624 | }; | 622 | }; |
625 | 623 | ||
626 | 624 | ||
627 | /* This is called when the module is loaded */ | 625 | /* This is called when the module is loaded */ |
628 | static int via686a_detect(struct i2c_adapter *adapter) | 626 | static int __devinit via686a_probe(struct platform_device *pdev) |
629 | { | 627 | { |
630 | struct i2c_client *new_client; | ||
631 | struct via686a_data *data; | 628 | struct via686a_data *data; |
632 | int err = 0; | 629 | struct resource *res; |
633 | const char client_name[] = "via686a"; | 630 | 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 | 631 | ||
662 | /* Reserve the ISA region */ | 632 | /* Reserve the ISA region */ |
663 | if (!request_region(address, VIA686A_EXTENT, | 633 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
634 | if (!request_region(res->start, VIA686A_EXTENT, | ||
664 | via686a_driver.driver.name)) { | 635 | via686a_driver.driver.name)) { |
665 | dev_err(&adapter->dev, "region 0x%x already in use!\n", | 636 | dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n", |
666 | address); | 637 | (unsigned long)res->start, (unsigned long)res->end); |
667 | return -ENODEV; | 638 | return -ENODEV; |
668 | } | 639 | } |
669 | 640 | ||
@@ -672,30 +643,19 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
672 | goto exit_release; | 643 | goto exit_release; |
673 | } | 644 | } |
674 | 645 | ||
675 | new_client = &data->client; | 646 | platform_set_drvdata(pdev, data); |
676 | i2c_set_clientdata(new_client, data); | 647 | data->addr = res->start; |
677 | new_client->addr = address; | 648 | 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); | 649 | 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 | 650 | ||
691 | /* Initialize the VIA686A chip */ | 651 | /* Initialize the VIA686A chip */ |
692 | via686a_init_client(new_client); | 652 | via686a_init_device(data); |
693 | 653 | ||
694 | /* Register sysfs hooks */ | 654 | /* Register sysfs hooks */ |
695 | if ((err = sysfs_create_group(&new_client->dev.kobj, &via686a_group))) | 655 | if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group))) |
696 | goto exit_detach; | 656 | goto exit_free; |
697 | 657 | ||
698 | data->class_dev = hwmon_device_register(&new_client->dev); | 658 | data->class_dev = hwmon_device_register(&pdev->dev); |
699 | if (IS_ERR(data->class_dev)) { | 659 | if (IS_ERR(data->class_dev)) { |
700 | err = PTR_ERR(data->class_dev); | 660 | err = PTR_ERR(data->class_dev); |
701 | goto exit_remove_files; | 661 | goto exit_remove_files; |
@@ -704,52 +664,46 @@ static int via686a_detect(struct i2c_adapter *adapter) | |||
704 | return 0; | 664 | return 0; |
705 | 665 | ||
706 | exit_remove_files: | 666 | exit_remove_files: |
707 | sysfs_remove_group(&new_client->dev.kobj, &via686a_group); | 667 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
708 | exit_detach: | ||
709 | i2c_detach_client(new_client); | ||
710 | exit_free: | 668 | exit_free: |
711 | kfree(data); | 669 | kfree(data); |
712 | exit_release: | 670 | exit_release: |
713 | release_region(address, VIA686A_EXTENT); | 671 | release_region(res->start, VIA686A_EXTENT); |
714 | return err; | 672 | return err; |
715 | } | 673 | } |
716 | 674 | ||
717 | static int via686a_detach_client(struct i2c_client *client) | 675 | static int __devexit via686a_remove(struct platform_device *pdev) |
718 | { | 676 | { |
719 | struct via686a_data *data = i2c_get_clientdata(client); | 677 | struct via686a_data *data = platform_get_drvdata(pdev); |
720 | int err; | ||
721 | 678 | ||
722 | hwmon_device_unregister(data->class_dev); | 679 | hwmon_device_unregister(data->class_dev); |
723 | sysfs_remove_group(&client->dev.kobj, &via686a_group); | 680 | sysfs_remove_group(&pdev->dev.kobj, &via686a_group); |
724 | 681 | ||
725 | if ((err = i2c_detach_client(client))) | 682 | release_region(data->addr, VIA686A_EXTENT); |
726 | return err; | 683 | platform_set_drvdata(pdev, NULL); |
727 | |||
728 | release_region(client->addr, VIA686A_EXTENT); | ||
729 | kfree(data); | 684 | kfree(data); |
730 | 685 | ||
731 | return 0; | 686 | return 0; |
732 | } | 687 | } |
733 | 688 | ||
734 | static void via686a_init_client(struct i2c_client *client) | 689 | static void __devinit via686a_init_device(struct via686a_data *data) |
735 | { | 690 | { |
736 | u8 reg; | 691 | u8 reg; |
737 | 692 | ||
738 | /* Start monitoring */ | 693 | /* Start monitoring */ |
739 | reg = via686a_read_value(client, VIA686A_REG_CONFIG); | 694 | reg = via686a_read_value(data, VIA686A_REG_CONFIG); |
740 | via686a_write_value(client, VIA686A_REG_CONFIG, (reg|0x01)&0x7F); | 695 | via686a_write_value(data, VIA686A_REG_CONFIG, (reg | 0x01) & 0x7F); |
741 | 696 | ||
742 | /* Configure temp interrupt mode for continuous-interrupt operation */ | 697 | /* Configure temp interrupt mode for continuous-interrupt operation */ |
743 | reg = via686a_read_value(client, VIA686A_REG_TEMP_MODE); | 698 | reg = via686a_read_value(data, VIA686A_REG_TEMP_MODE); |
744 | via686a_write_value(client, VIA686A_REG_TEMP_MODE, | 699 | via686a_write_value(data, VIA686A_REG_TEMP_MODE, |
745 | (reg & ~VIA686A_TEMP_MODE_MASK) | 700 | (reg & ~VIA686A_TEMP_MODE_MASK) |
746 | | VIA686A_TEMP_MODE_CONTINUOUS); | 701 | | VIA686A_TEMP_MODE_CONTINUOUS); |
747 | } | 702 | } |
748 | 703 | ||
749 | static struct via686a_data *via686a_update_device(struct device *dev) | 704 | static struct via686a_data *via686a_update_device(struct device *dev) |
750 | { | 705 | { |
751 | struct i2c_client *client = to_i2c_client(dev); | 706 | struct via686a_data *data = dev_get_drvdata(dev); |
752 | struct via686a_data *data = i2c_get_clientdata(client); | ||
753 | int i; | 707 | int i; |
754 | 708 | ||
755 | mutex_lock(&data->update_lock); | 709 | mutex_lock(&data->update_lock); |
@@ -758,27 +712,27 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
758 | || !data->valid) { | 712 | || !data->valid) { |
759 | for (i = 0; i <= 4; i++) { | 713 | for (i = 0; i <= 4; i++) { |
760 | data->in[i] = | 714 | data->in[i] = |
761 | via686a_read_value(client, VIA686A_REG_IN(i)); | 715 | via686a_read_value(data, VIA686A_REG_IN(i)); |
762 | data->in_min[i] = via686a_read_value(client, | 716 | data->in_min[i] = via686a_read_value(data, |
763 | VIA686A_REG_IN_MIN | 717 | VIA686A_REG_IN_MIN |
764 | (i)); | 718 | (i)); |
765 | data->in_max[i] = | 719 | data->in_max[i] = |
766 | via686a_read_value(client, VIA686A_REG_IN_MAX(i)); | 720 | via686a_read_value(data, VIA686A_REG_IN_MAX(i)); |
767 | } | 721 | } |
768 | for (i = 1; i <= 2; i++) { | 722 | for (i = 1; i <= 2; i++) { |
769 | data->fan[i - 1] = | 723 | data->fan[i - 1] = |
770 | via686a_read_value(client, VIA686A_REG_FAN(i)); | 724 | via686a_read_value(data, VIA686A_REG_FAN(i)); |
771 | data->fan_min[i - 1] = via686a_read_value(client, | 725 | data->fan_min[i - 1] = via686a_read_value(data, |
772 | VIA686A_REG_FAN_MIN(i)); | 726 | VIA686A_REG_FAN_MIN(i)); |
773 | } | 727 | } |
774 | for (i = 0; i <= 2; i++) { | 728 | for (i = 0; i <= 2; i++) { |
775 | data->temp[i] = via686a_read_value(client, | 729 | data->temp[i] = via686a_read_value(data, |
776 | VIA686A_REG_TEMP[i]) << 2; | 730 | VIA686A_REG_TEMP[i]) << 2; |
777 | data->temp_over[i] = | 731 | data->temp_over[i] = |
778 | via686a_read_value(client, | 732 | via686a_read_value(data, |
779 | VIA686A_REG_TEMP_OVER[i]); | 733 | VIA686A_REG_TEMP_OVER[i]); |
780 | data->temp_hyst[i] = | 734 | data->temp_hyst[i] = |
781 | via686a_read_value(client, | 735 | via686a_read_value(data, |
782 | VIA686A_REG_TEMP_HYST[i]); | 736 | VIA686A_REG_TEMP_HYST[i]); |
783 | } | 737 | } |
784 | /* add in lower 2 bits | 738 | /* add in lower 2 bits |
@@ -786,23 +740,23 @@ static struct via686a_data *via686a_update_device(struct device *dev) | |||
786 | temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 | 740 | temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23 |
787 | temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 | 741 | temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23 |
788 | */ | 742 | */ |
789 | data->temp[0] |= (via686a_read_value(client, | 743 | data->temp[0] |= (via686a_read_value(data, |
790 | VIA686A_REG_TEMP_LOW1) | 744 | VIA686A_REG_TEMP_LOW1) |
791 | & 0xc0) >> 6; | 745 | & 0xc0) >> 6; |
792 | data->temp[1] |= | 746 | data->temp[1] |= |
793 | (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & | 747 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
794 | 0x30) >> 4; | 748 | 0x30) >> 4; |
795 | data->temp[2] |= | 749 | data->temp[2] |= |
796 | (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) & | 750 | (via686a_read_value(data, VIA686A_REG_TEMP_LOW23) & |
797 | 0xc0) >> 6; | 751 | 0xc0) >> 6; |
798 | 752 | ||
799 | i = via686a_read_value(client, VIA686A_REG_FANDIV); | 753 | i = via686a_read_value(data, VIA686A_REG_FANDIV); |
800 | data->fan_div[0] = (i >> 4) & 0x03; | 754 | data->fan_div[0] = (i >> 4) & 0x03; |
801 | data->fan_div[1] = i >> 6; | 755 | data->fan_div[1] = i >> 6; |
802 | data->alarms = | 756 | data->alarms = |
803 | via686a_read_value(client, | 757 | via686a_read_value(data, |
804 | VIA686A_REG_ALARM1) | | 758 | VIA686A_REG_ALARM1) | |
805 | (via686a_read_value(client, VIA686A_REG_ALARM2) << 8); | 759 | (via686a_read_value(data, VIA686A_REG_ALARM2) << 8); |
806 | data->last_updated = jiffies; | 760 | data->last_updated = jiffies; |
807 | data->valid = 1; | 761 | data->valid = 1; |
808 | } | 762 | } |
@@ -819,32 +773,102 @@ static struct pci_device_id via686a_pci_ids[] = { | |||
819 | 773 | ||
820 | MODULE_DEVICE_TABLE(pci, via686a_pci_ids); | 774 | MODULE_DEVICE_TABLE(pci, via686a_pci_ids); |
821 | 775 | ||
776 | static int __devinit via686a_device_add(unsigned short address) | ||
777 | { | ||
778 | struct resource res = { | ||
779 | .start = address, | ||
780 | .end = address + VIA686A_EXTENT - 1, | ||
781 | .name = "via686a", | ||
782 | .flags = IORESOURCE_IO, | ||
783 | }; | ||
784 | int err; | ||
785 | |||
786 | pdev = platform_device_alloc("via686a", address); | ||
787 | if (!pdev) { | ||
788 | err = -ENOMEM; | ||
789 | printk(KERN_ERR "via686a: Device allocation failed\n"); | ||
790 | goto exit; | ||
791 | } | ||
792 | |||
793 | err = platform_device_add_resources(pdev, &res, 1); | ||
794 | if (err) { | ||
795 | printk(KERN_ERR "via686a: Device resource addition failed " | ||
796 | "(%d)\n", err); | ||
797 | goto exit_device_put; | ||
798 | } | ||
799 | |||
800 | err = platform_device_add(pdev); | ||
801 | if (err) { | ||
802 | printk(KERN_ERR "via686a: Device addition failed (%d)\n", | ||
803 | err); | ||
804 | goto exit_device_put; | ||
805 | } | ||
806 | |||
807 | return 0; | ||
808 | |||
809 | exit_device_put: | ||
810 | platform_device_put(pdev); | ||
811 | exit: | ||
812 | return err; | ||
813 | } | ||
814 | |||
822 | static int __devinit via686a_pci_probe(struct pci_dev *dev, | 815 | static int __devinit via686a_pci_probe(struct pci_dev *dev, |
823 | const struct pci_device_id *id) | 816 | const struct pci_device_id *id) |
824 | { | 817 | { |
825 | u16 val; | 818 | u16 address, val; |
826 | 819 | ||
820 | if (force_addr) { | ||
821 | address = force_addr & ~(VIA686A_EXTENT - 1); | ||
822 | dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", address); | ||
823 | if (PCIBIOS_SUCCESSFUL != | ||
824 | pci_write_config_word(dev, VIA686A_BASE_REG, address | 1)) | ||
825 | return -ENODEV; | ||
826 | } | ||
827 | if (PCIBIOS_SUCCESSFUL != | 827 | if (PCIBIOS_SUCCESSFUL != |
828 | pci_read_config_word(dev, VIA686A_BASE_REG, &val)) | 828 | pci_read_config_word(dev, VIA686A_BASE_REG, &val)) |
829 | return -ENODEV; | 829 | return -ENODEV; |
830 | 830 | ||
831 | address = val & ~(VIA686A_EXTENT - 1); | 831 | address = val & ~(VIA686A_EXTENT - 1); |
832 | if (address == 0 && force_addr == 0) { | 832 | if (address == 0) { |
833 | dev_err(&dev->dev, "base address not set - upgrade BIOS " | 833 | dev_err(&dev->dev, "base address not set - upgrade BIOS " |
834 | "or use force_addr=0xaddr\n"); | 834 | "or use force_addr=0xaddr\n"); |
835 | return -ENODEV; | 835 | return -ENODEV; |
836 | } | 836 | } |
837 | 837 | ||
838 | s_bridge = pci_dev_get(dev); | 838 | if (PCIBIOS_SUCCESSFUL != |
839 | if (i2c_isa_add_driver(&via686a_driver)) { | 839 | pci_read_config_word(dev, VIA686A_ENABLE_REG, &val)) |
840 | pci_dev_put(s_bridge); | 840 | return -ENODEV; |
841 | s_bridge = NULL; | 841 | if (!(val & 0x0001)) { |
842 | if (!force_addr) { | ||
843 | dev_warn(&dev->dev, "Sensors disabled, enable " | ||
844 | "with force_addr=0x%x\n", address); | ||
845 | return -ENODEV; | ||
846 | } | ||
847 | |||
848 | dev_warn(&dev->dev, "Enabling sensors\n"); | ||
849 | if (PCIBIOS_SUCCESSFUL != | ||
850 | pci_write_config_word(dev, VIA686A_ENABLE_REG, | ||
851 | val | 0x0001)) | ||
852 | return -ENODEV; | ||
842 | } | 853 | } |
843 | 854 | ||
855 | if (platform_driver_register(&via686a_driver)) | ||
856 | goto exit; | ||
857 | |||
858 | /* Sets global pdev as a side effect */ | ||
859 | if (via686a_device_add(address)) | ||
860 | goto exit_unregister; | ||
861 | |||
844 | /* Always return failure here. This is to allow other drivers to bind | 862 | /* Always return failure here. This is to allow other drivers to bind |
845 | * to this pci device. We don't really want to have control over the | 863 | * to this pci device. We don't really want to have control over the |
846 | * pci device, we only wanted to read as few register values from it. | 864 | * pci device, we only wanted to read as few register values from it. |
847 | */ | 865 | */ |
866 | s_bridge = pci_dev_get(dev); | ||
867 | return -ENODEV; | ||
868 | |||
869 | exit_unregister: | ||
870 | platform_driver_unregister(&via686a_driver); | ||
871 | exit: | ||
848 | return -ENODEV; | 872 | return -ENODEV; |
849 | } | 873 | } |
850 | 874 | ||
@@ -863,7 +887,8 @@ static void __exit sm_via686a_exit(void) | |||
863 | { | 887 | { |
864 | pci_unregister_driver(&via686a_pci_driver); | 888 | pci_unregister_driver(&via686a_pci_driver); |
865 | if (s_bridge != NULL) { | 889 | if (s_bridge != NULL) { |
866 | i2c_isa_del_driver(&via686a_driver); | 890 | platform_device_unregister(pdev); |
891 | platform_driver_unregister(&via686a_driver); | ||
867 | pci_dev_put(s_bridge); | 892 | pci_dev_put(s_bridge); |
868 | s_bridge = NULL; | 893 | s_bridge = NULL; |
869 | } | 894 | } |