diff options
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r-- | drivers/hwmon/it87.c | 234 |
1 files changed, 149 insertions, 85 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index af5740d5d70f..323ef06719c1 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/hwmon-vid.h> | 37 | #include <linux/hwmon-vid.h> |
38 | #include <linux/err.h> | 38 | #include <linux/err.h> |
39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | #include <linux/sysfs.h> | ||
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | 42 | ||
42 | 43 | ||
@@ -758,8 +759,6 @@ store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf | |||
758 | return count; | 759 | return count; |
759 | } | 760 | } |
760 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); | 761 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); |
761 | #define device_create_file_vrm(client) \ | ||
762 | device_create_file(&client->dev, &dev_attr_vrm) | ||
763 | 762 | ||
764 | static ssize_t | 763 | static ssize_t |
765 | show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | 764 | show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -768,8 +767,88 @@ show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) | |||
768 | return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); | 767 | return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); |
769 | } | 768 | } |
770 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 769 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
771 | #define device_create_file_vid(client) \ | 770 | |
772 | device_create_file(&client->dev, &dev_attr_cpu0_vid) | 771 | static struct attribute *it87_attributes[] = { |
772 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
773 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
774 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
775 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
776 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
777 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
778 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
779 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
780 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
781 | &sensor_dev_attr_in0_min.dev_attr.attr, | ||
782 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
783 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
784 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
785 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
786 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
787 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
788 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
789 | &sensor_dev_attr_in0_max.dev_attr.attr, | ||
790 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
791 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
792 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
793 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
794 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
795 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
796 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
797 | |||
798 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
799 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
800 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
801 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
802 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
803 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
804 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
805 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
806 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
807 | &sensor_dev_attr_temp1_type.dev_attr.attr, | ||
808 | &sensor_dev_attr_temp2_type.dev_attr.attr, | ||
809 | &sensor_dev_attr_temp3_type.dev_attr.attr, | ||
810 | |||
811 | &dev_attr_alarms.attr, | ||
812 | NULL | ||
813 | }; | ||
814 | |||
815 | static const struct attribute_group it87_group = { | ||
816 | .attrs = it87_attributes, | ||
817 | }; | ||
818 | |||
819 | static struct attribute *it87_attributes_opt[] = { | ||
820 | &sensor_dev_attr_fan1_input16.dev_attr.attr, | ||
821 | &sensor_dev_attr_fan1_min16.dev_attr.attr, | ||
822 | &sensor_dev_attr_fan2_input16.dev_attr.attr, | ||
823 | &sensor_dev_attr_fan2_min16.dev_attr.attr, | ||
824 | &sensor_dev_attr_fan3_input16.dev_attr.attr, | ||
825 | &sensor_dev_attr_fan3_min16.dev_attr.attr, | ||
826 | |||
827 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
828 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
829 | &sensor_dev_attr_fan1_div.dev_attr.attr, | ||
830 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
831 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
832 | &sensor_dev_attr_fan2_div.dev_attr.attr, | ||
833 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
834 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
835 | &sensor_dev_attr_fan3_div.dev_attr.attr, | ||
836 | |||
837 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
838 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
839 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
840 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
841 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
842 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
843 | |||
844 | &dev_attr_vrm.attr, | ||
845 | &dev_attr_cpu0_vid.attr, | ||
846 | NULL | ||
847 | }; | ||
848 | |||
849 | static const struct attribute_group it87_group_opt = { | ||
850 | .attrs = it87_attributes_opt, | ||
851 | }; | ||
773 | 852 | ||
774 | /* This function is called when: | 853 | /* This function is called when: |
775 | * it87_driver is inserted (when this module is loaded), for each | 854 | * it87_driver is inserted (when this module is loaded), for each |
@@ -948,107 +1027,78 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
948 | it87_init_client(new_client, data); | 1027 | it87_init_client(new_client, data); |
949 | 1028 | ||
950 | /* Register sysfs hooks */ | 1029 | /* Register sysfs hooks */ |
951 | data->class_dev = hwmon_device_register(&new_client->dev); | 1030 | if ((err = sysfs_create_group(&new_client->dev.kobj, &it87_group))) |
952 | if (IS_ERR(data->class_dev)) { | ||
953 | err = PTR_ERR(data->class_dev); | ||
954 | goto ERROR3; | 1031 | goto ERROR3; |
955 | } | ||
956 | |||
957 | device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr); | ||
958 | device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr); | ||
959 | device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr); | ||
960 | device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr); | ||
961 | device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr); | ||
962 | device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr); | ||
963 | device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr); | ||
964 | device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr); | ||
965 | device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr); | ||
966 | device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr); | ||
967 | device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr); | ||
968 | device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr); | ||
969 | device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr); | ||
970 | device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr); | ||
971 | device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr); | ||
972 | device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr); | ||
973 | device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr); | ||
974 | device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr); | ||
975 | device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr); | ||
976 | device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr); | ||
977 | device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr); | ||
978 | device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr); | ||
979 | device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr); | ||
980 | device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr); | ||
981 | device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr); | ||
982 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr); | ||
983 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr); | ||
984 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr); | ||
985 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
986 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr); | ||
987 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr); | ||
988 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr); | ||
989 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr); | ||
990 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr); | ||
991 | device_create_file(&new_client->dev, &sensor_dev_attr_temp1_type.dev_attr); | ||
992 | device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr); | ||
993 | device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr); | ||
994 | 1032 | ||
995 | /* Do not create fan files for disabled fans */ | 1033 | /* Do not create fan files for disabled fans */ |
996 | if (data->type == it8716 || data->type == it8718) { | 1034 | if (data->type == it8716 || data->type == it8718) { |
997 | /* 16-bit tachometers */ | 1035 | /* 16-bit tachometers */ |
998 | if (data->has_fan & (1 << 0)) { | 1036 | if (data->has_fan & (1 << 0)) { |
999 | device_create_file(&new_client->dev, | 1037 | if ((err = device_create_file(&new_client->dev, |
1000 | &sensor_dev_attr_fan1_input16.dev_attr); | 1038 | &sensor_dev_attr_fan1_input16.dev_attr)) |
1001 | device_create_file(&new_client->dev, | 1039 | || (err = device_create_file(&new_client->dev, |
1002 | &sensor_dev_attr_fan1_min16.dev_attr); | 1040 | &sensor_dev_attr_fan1_min16.dev_attr))) |
1041 | goto ERROR4; | ||
1003 | } | 1042 | } |
1004 | if (data->has_fan & (1 << 1)) { | 1043 | if (data->has_fan & (1 << 1)) { |
1005 | device_create_file(&new_client->dev, | 1044 | if ((err = device_create_file(&new_client->dev, |
1006 | &sensor_dev_attr_fan2_input16.dev_attr); | 1045 | &sensor_dev_attr_fan2_input16.dev_attr)) |
1007 | device_create_file(&new_client->dev, | 1046 | || (err = device_create_file(&new_client->dev, |
1008 | &sensor_dev_attr_fan2_min16.dev_attr); | 1047 | &sensor_dev_attr_fan2_min16.dev_attr))) |
1048 | goto ERROR4; | ||
1009 | } | 1049 | } |
1010 | if (data->has_fan & (1 << 2)) { | 1050 | if (data->has_fan & (1 << 2)) { |
1011 | device_create_file(&new_client->dev, | 1051 | if ((err = device_create_file(&new_client->dev, |
1012 | &sensor_dev_attr_fan3_input16.dev_attr); | 1052 | &sensor_dev_attr_fan3_input16.dev_attr)) |
1013 | device_create_file(&new_client->dev, | 1053 | || (err = device_create_file(&new_client->dev, |
1014 | &sensor_dev_attr_fan3_min16.dev_attr); | 1054 | &sensor_dev_attr_fan3_min16.dev_attr))) |
1055 | goto ERROR4; | ||
1015 | } | 1056 | } |
1016 | } else { | 1057 | } else { |
1017 | /* 8-bit tachometers with clock divider */ | 1058 | /* 8-bit tachometers with clock divider */ |
1018 | if (data->has_fan & (1 << 0)) { | 1059 | if (data->has_fan & (1 << 0)) { |
1019 | device_create_file(&new_client->dev, | 1060 | if ((err = device_create_file(&new_client->dev, |
1020 | &sensor_dev_attr_fan1_input.dev_attr); | 1061 | &sensor_dev_attr_fan1_input.dev_attr)) |
1021 | device_create_file(&new_client->dev, | 1062 | || (err = device_create_file(&new_client->dev, |
1022 | &sensor_dev_attr_fan1_min.dev_attr); | 1063 | &sensor_dev_attr_fan1_min.dev_attr)) |
1023 | device_create_file(&new_client->dev, | 1064 | || (err = device_create_file(&new_client->dev, |
1024 | &sensor_dev_attr_fan1_div.dev_attr); | 1065 | &sensor_dev_attr_fan1_div.dev_attr))) |
1066 | goto ERROR4; | ||
1025 | } | 1067 | } |
1026 | if (data->has_fan & (1 << 1)) { | 1068 | if (data->has_fan & (1 << 1)) { |
1027 | device_create_file(&new_client->dev, | 1069 | if ((err = device_create_file(&new_client->dev, |
1028 | &sensor_dev_attr_fan2_input.dev_attr); | 1070 | &sensor_dev_attr_fan2_input.dev_attr)) |
1029 | device_create_file(&new_client->dev, | 1071 | || (err = device_create_file(&new_client->dev, |
1030 | &sensor_dev_attr_fan2_min.dev_attr); | 1072 | &sensor_dev_attr_fan2_min.dev_attr)) |
1031 | device_create_file(&new_client->dev, | 1073 | || (err = device_create_file(&new_client->dev, |
1032 | &sensor_dev_attr_fan2_div.dev_attr); | 1074 | &sensor_dev_attr_fan2_div.dev_attr))) |
1075 | goto ERROR4; | ||
1033 | } | 1076 | } |
1034 | if (data->has_fan & (1 << 2)) { | 1077 | if (data->has_fan & (1 << 2)) { |
1035 | device_create_file(&new_client->dev, | 1078 | if ((err = device_create_file(&new_client->dev, |
1036 | &sensor_dev_attr_fan3_input.dev_attr); | 1079 | &sensor_dev_attr_fan3_input.dev_attr)) |
1037 | device_create_file(&new_client->dev, | 1080 | || (err = device_create_file(&new_client->dev, |
1038 | &sensor_dev_attr_fan3_min.dev_attr); | 1081 | &sensor_dev_attr_fan3_min.dev_attr)) |
1039 | device_create_file(&new_client->dev, | 1082 | || (err = device_create_file(&new_client->dev, |
1040 | &sensor_dev_attr_fan3_div.dev_attr); | 1083 | &sensor_dev_attr_fan3_div.dev_attr))) |
1084 | goto ERROR4; | ||
1041 | } | 1085 | } |
1042 | } | 1086 | } |
1043 | 1087 | ||
1044 | device_create_file(&new_client->dev, &dev_attr_alarms); | ||
1045 | if (enable_pwm_interface) { | 1088 | if (enable_pwm_interface) { |
1046 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm1_enable.dev_attr); | 1089 | if ((err = device_create_file(&new_client->dev, |
1047 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm2_enable.dev_attr); | 1090 | &sensor_dev_attr_pwm1_enable.dev_attr)) |
1048 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm3_enable.dev_attr); | 1091 | || (err = device_create_file(&new_client->dev, |
1049 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm1.dev_attr); | 1092 | &sensor_dev_attr_pwm2_enable.dev_attr)) |
1050 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm2.dev_attr); | 1093 | || (err = device_create_file(&new_client->dev, |
1051 | device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr); | 1094 | &sensor_dev_attr_pwm3_enable.dev_attr)) |
1095 | || (err = device_create_file(&new_client->dev, | ||
1096 | &sensor_dev_attr_pwm1.dev_attr)) | ||
1097 | || (err = device_create_file(&new_client->dev, | ||
1098 | &sensor_dev_attr_pwm2.dev_attr)) | ||
1099 | || (err = device_create_file(&new_client->dev, | ||
1100 | &sensor_dev_attr_pwm3.dev_attr))) | ||
1101 | goto ERROR4; | ||
1052 | } | 1102 | } |
1053 | 1103 | ||
1054 | if (data->type == it8712 || data->type == it8716 | 1104 | if (data->type == it8712 || data->type == it8716 |
@@ -1056,12 +1106,24 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1056 | data->vrm = vid_which_vrm(); | 1106 | data->vrm = vid_which_vrm(); |
1057 | /* VID reading from Super-I/O config space if available */ | 1107 | /* VID reading from Super-I/O config space if available */ |
1058 | data->vid = vid_value; | 1108 | data->vid = vid_value; |
1059 | device_create_file_vrm(new_client); | 1109 | if ((err = device_create_file(&new_client->dev, |
1060 | device_create_file_vid(new_client); | 1110 | &dev_attr_vrm)) |
1111 | || (err = device_create_file(&new_client->dev, | ||
1112 | &dev_attr_cpu0_vid))) | ||
1113 | goto ERROR4; | ||
1114 | } | ||
1115 | |||
1116 | data->class_dev = hwmon_device_register(&new_client->dev); | ||
1117 | if (IS_ERR(data->class_dev)) { | ||
1118 | err = PTR_ERR(data->class_dev); | ||
1119 | goto ERROR4; | ||
1061 | } | 1120 | } |
1062 | 1121 | ||
1063 | return 0; | 1122 | return 0; |
1064 | 1123 | ||
1124 | ERROR4: | ||
1125 | sysfs_remove_group(&new_client->dev.kobj, &it87_group); | ||
1126 | sysfs_remove_group(&new_client->dev.kobj, &it87_group_opt); | ||
1065 | ERROR3: | 1127 | ERROR3: |
1066 | i2c_detach_client(new_client); | 1128 | i2c_detach_client(new_client); |
1067 | ERROR2: | 1129 | ERROR2: |
@@ -1079,6 +1141,8 @@ static int it87_detach_client(struct i2c_client *client) | |||
1079 | int err; | 1141 | int err; |
1080 | 1142 | ||
1081 | hwmon_device_unregister(data->class_dev); | 1143 | hwmon_device_unregister(data->class_dev); |
1144 | sysfs_remove_group(&client->dev.kobj, &it87_group); | ||
1145 | sysfs_remove_group(&client->dev.kobj, &it87_group_opt); | ||
1082 | 1146 | ||
1083 | if ((err = i2c_detach_client(client))) | 1147 | if ((err = i2c_detach_client(client))) |
1084 | return err; | 1148 | return err; |