diff options
-rw-r--r-- | drivers/hwmon/vt8231.c | 186 |
1 files changed, 132 insertions, 54 deletions
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c index 236ccf0e915d..93f93d4fb8ae 100644 --- a/drivers/hwmon/vt8231.c +++ b/drivers/hwmon/vt8231.c | |||
@@ -451,37 +451,6 @@ define_temperature_sysfs(4); | |||
451 | define_temperature_sysfs(5); | 451 | define_temperature_sysfs(5); |
452 | define_temperature_sysfs(6); | 452 | define_temperature_sysfs(6); |
453 | 453 | ||
454 | #define CFG_INFO_TEMP(id) { &sensor_dev_attr_temp##id##_input.dev_attr, \ | ||
455 | &sensor_dev_attr_temp##id##_max_hyst.dev_attr, \ | ||
456 | &sensor_dev_attr_temp##id##_max.dev_attr } | ||
457 | #define CFG_INFO_VOLT(id) { &sensor_dev_attr_in##id##_input.dev_attr, \ | ||
458 | &sensor_dev_attr_in##id##_min.dev_attr, \ | ||
459 | &sensor_dev_attr_in##id##_max.dev_attr } | ||
460 | |||
461 | struct str_device_attr_table { | ||
462 | struct device_attribute *input; | ||
463 | struct device_attribute *min; | ||
464 | struct device_attribute *max; | ||
465 | }; | ||
466 | |||
467 | static struct str_device_attr_table cfg_info_temp[] = { | ||
468 | { &dev_attr_temp1_input, &dev_attr_temp1_max_hyst, &dev_attr_temp1_max }, | ||
469 | CFG_INFO_TEMP(2), | ||
470 | CFG_INFO_TEMP(3), | ||
471 | CFG_INFO_TEMP(4), | ||
472 | CFG_INFO_TEMP(5), | ||
473 | CFG_INFO_TEMP(6) | ||
474 | }; | ||
475 | |||
476 | static struct str_device_attr_table cfg_info_volt[] = { | ||
477 | CFG_INFO_VOLT(0), | ||
478 | CFG_INFO_VOLT(1), | ||
479 | CFG_INFO_VOLT(2), | ||
480 | CFG_INFO_VOLT(3), | ||
481 | CFG_INFO_VOLT(4), | ||
482 | { &dev_attr_in5_input, &dev_attr_in5_min, &dev_attr_in5_max } | ||
483 | }; | ||
484 | |||
485 | /* Fans */ | 454 | /* Fans */ |
486 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, | 455 | static ssize_t show_fan(struct device *dev, struct device_attribute *attr, |
487 | char *buf) | 456 | char *buf) |
@@ -585,6 +554,107 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, | |||
585 | 554 | ||
586 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 555 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
587 | 556 | ||
557 | static struct attribute *vt8231_attributes_temps[6][4] = { | ||
558 | { | ||
559 | &dev_attr_temp1_input.attr, | ||
560 | &dev_attr_temp1_max_hyst.attr, | ||
561 | &dev_attr_temp1_max.attr, | ||
562 | NULL | ||
563 | }, { | ||
564 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
565 | &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, | ||
566 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
567 | NULL | ||
568 | }, { | ||
569 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
570 | &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, | ||
571 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
572 | NULL | ||
573 | }, { | ||
574 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
575 | &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, | ||
576 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
577 | NULL | ||
578 | }, { | ||
579 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
580 | &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, | ||
581 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
582 | NULL | ||
583 | }, { | ||
584 | &sensor_dev_attr_temp6_input.dev_attr.attr, | ||
585 | &sensor_dev_attr_temp6_max_hyst.dev_attr.attr, | ||
586 | &sensor_dev_attr_temp6_max.dev_attr.attr, | ||
587 | NULL | ||
588 | } | ||
589 | }; | ||
590 | |||
591 | static const struct attribute_group vt8231_group_temps[6] = { | ||
592 | { .attrs = vt8231_attributes_temps[0] }, | ||
593 | { .attrs = vt8231_attributes_temps[1] }, | ||
594 | { .attrs = vt8231_attributes_temps[2] }, | ||
595 | { .attrs = vt8231_attributes_temps[3] }, | ||
596 | { .attrs = vt8231_attributes_temps[4] }, | ||
597 | { .attrs = vt8231_attributes_temps[5] }, | ||
598 | }; | ||
599 | |||
600 | static struct attribute *vt8231_attributes_volts[6][4] = { | ||
601 | { | ||
602 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
603 | &sensor_dev_attr_in0_min.dev_attr.attr, | ||
604 | &sensor_dev_attr_in0_max.dev_attr.attr, | ||
605 | NULL | ||
606 | }, { | ||
607 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
608 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
609 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
610 | NULL | ||
611 | }, { | ||
612 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
613 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
614 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
615 | NULL | ||
616 | }, { | ||
617 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
618 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
619 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
620 | NULL | ||
621 | }, { | ||
622 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
623 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
624 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
625 | NULL | ||
626 | }, { | ||
627 | &dev_attr_in5_input.attr, | ||
628 | &dev_attr_in5_min.attr, | ||
629 | &dev_attr_in5_max.attr, | ||
630 | NULL | ||
631 | } | ||
632 | }; | ||
633 | |||
634 | static const struct attribute_group vt8231_group_volts[6] = { | ||
635 | { .attrs = vt8231_attributes_volts[0] }, | ||
636 | { .attrs = vt8231_attributes_volts[1] }, | ||
637 | { .attrs = vt8231_attributes_volts[2] }, | ||
638 | { .attrs = vt8231_attributes_volts[3] }, | ||
639 | { .attrs = vt8231_attributes_volts[4] }, | ||
640 | { .attrs = vt8231_attributes_volts[5] }, | ||
641 | }; | ||
642 | |||
643 | static struct attribute *vt8231_attributes[] = { | ||
644 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
645 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
646 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
647 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
648 | &sensor_dev_attr_fan1_div.dev_attr.attr, | ||
649 | &sensor_dev_attr_fan2_div.dev_attr.attr, | ||
650 | &dev_attr_alarms.attr, | ||
651 | NULL | ||
652 | }; | ||
653 | |||
654 | static const struct attribute_group vt8231_group = { | ||
655 | .attrs = vt8231_attributes, | ||
656 | }; | ||
657 | |||
588 | static struct i2c_driver vt8231_driver = { | 658 | static struct i2c_driver vt8231_driver = { |
589 | .driver = { | 659 | .driver = { |
590 | .owner = THIS_MODULE, | 660 | .owner = THIS_MODULE, |
@@ -671,43 +741,43 @@ int vt8231_detect(struct i2c_adapter *adapter) | |||
671 | vt8231_init_client(client); | 741 | vt8231_init_client(client); |
672 | 742 | ||
673 | /* Register sysfs hooks */ | 743 | /* Register sysfs hooks */ |
674 | data->class_dev = hwmon_device_register(&client->dev); | 744 | if ((err = sysfs_create_group(&client->dev.kobj, &vt8231_group))) |
675 | if (IS_ERR(data->class_dev)) { | ||
676 | err = PTR_ERR(data->class_dev); | ||
677 | goto exit_detach; | 745 | goto exit_detach; |
678 | } | ||
679 | 746 | ||
680 | /* Must update device information to find out the config field */ | 747 | /* Must update device information to find out the config field */ |
681 | data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG); | 748 | data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG); |
682 | 749 | ||
683 | for (i = 0; i < ARRAY_SIZE(cfg_info_temp); i++) { | 750 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) { |
684 | if (ISTEMP(i, data->uch_config)) { | 751 | if (ISTEMP(i, data->uch_config)) { |
685 | device_create_file(&client->dev, | 752 | if ((err = sysfs_create_group(&client->dev.kobj, |
686 | cfg_info_temp[i].input); | 753 | &vt8231_group_temps[i]))) |
687 | device_create_file(&client->dev, cfg_info_temp[i].max); | 754 | goto exit_remove_files; |
688 | device_create_file(&client->dev, cfg_info_temp[i].min); | ||
689 | } | 755 | } |
690 | } | 756 | } |
691 | 757 | ||
692 | for (i = 0; i < ARRAY_SIZE(cfg_info_volt); i++) { | 758 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) { |
693 | if (ISVOLT(i, data->uch_config)) { | 759 | if (ISVOLT(i, data->uch_config)) { |
694 | device_create_file(&client->dev, | 760 | if ((err = sysfs_create_group(&client->dev.kobj, |
695 | cfg_info_volt[i].input); | 761 | &vt8231_group_volts[i]))) |
696 | device_create_file(&client->dev, cfg_info_volt[i].max); | 762 | goto exit_remove_files; |
697 | device_create_file(&client->dev, cfg_info_volt[i].min); | ||
698 | } | 763 | } |
699 | } | 764 | } |
700 | 765 | ||
701 | device_create_file(&client->dev, &sensor_dev_attr_fan1_input.dev_attr); | 766 | data->class_dev = hwmon_device_register(&client->dev); |
702 | device_create_file(&client->dev, &sensor_dev_attr_fan2_input.dev_attr); | 767 | if (IS_ERR(data->class_dev)) { |
703 | device_create_file(&client->dev, &sensor_dev_attr_fan1_min.dev_attr); | 768 | err = PTR_ERR(data->class_dev); |
704 | device_create_file(&client->dev, &sensor_dev_attr_fan2_min.dev_attr); | 769 | goto exit_remove_files; |
705 | device_create_file(&client->dev, &sensor_dev_attr_fan1_div.dev_attr); | 770 | } |
706 | device_create_file(&client->dev, &sensor_dev_attr_fan2_div.dev_attr); | ||
707 | |||
708 | device_create_file(&client->dev, &dev_attr_alarms); | ||
709 | return 0; | 771 | return 0; |
710 | 772 | ||
773 | exit_remove_files: | ||
774 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) | ||
775 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]); | ||
776 | |||
777 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) | ||
778 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]); | ||
779 | |||
780 | sysfs_remove_group(&client->dev.kobj, &vt8231_group); | ||
711 | exit_detach: | 781 | exit_detach: |
712 | i2c_detach_client(client); | 782 | i2c_detach_client(client); |
713 | exit_free: | 783 | exit_free: |
@@ -720,10 +790,18 @@ exit_release: | |||
720 | static int vt8231_detach_client(struct i2c_client *client) | 790 | static int vt8231_detach_client(struct i2c_client *client) |
721 | { | 791 | { |
722 | struct vt8231_data *data = i2c_get_clientdata(client); | 792 | struct vt8231_data *data = i2c_get_clientdata(client); |
723 | int err; | 793 | int err, i; |
724 | 794 | ||
725 | hwmon_device_unregister(data->class_dev); | 795 | hwmon_device_unregister(data->class_dev); |
726 | 796 | ||
797 | for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) | ||
798 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_volts[i]); | ||
799 | |||
800 | for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) | ||
801 | sysfs_remove_group(&client->dev.kobj, &vt8231_group_temps[i]); | ||
802 | |||
803 | sysfs_remove_group(&client->dev.kobj, &vt8231_group); | ||
804 | |||
727 | if ((err = i2c_detach_client(client))) { | 805 | if ((err = i2c_detach_client(client))) { |
728 | return err; | 806 | return err; |
729 | } | 807 | } |