diff options
Diffstat (limited to 'drivers/hwmon/it87.c')
| -rw-r--r-- | drivers/hwmon/it87.c | 70 |
1 files changed, 51 insertions, 19 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index f1133081cc42..d793cc011990 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
| @@ -46,6 +46,8 @@ | |||
| 46 | #include <linux/err.h> | 46 | #include <linux/err.h> |
| 47 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
| 48 | #include <linux/sysfs.h> | 48 | #include <linux/sysfs.h> |
| 49 | #include <linux/string.h> | ||
| 50 | #include <linux/dmi.h> | ||
| 49 | #include <asm/io.h> | 51 | #include <asm/io.h> |
| 50 | 52 | ||
| 51 | #define DRVNAME "it87" | 53 | #define DRVNAME "it87" |
| @@ -236,6 +238,8 @@ struct it87_sio_data { | |||
| 236 | /* Values read from Super-I/O config space */ | 238 | /* Values read from Super-I/O config space */ |
| 237 | u8 revision; | 239 | u8 revision; |
| 238 | u8 vid_value; | 240 | u8 vid_value; |
| 241 | /* Values set based on DMI strings */ | ||
| 242 | u8 skip_pwm; | ||
| 239 | }; | 243 | }; |
| 240 | 244 | ||
| 241 | /* For each registered chip, we need to keep some data in memory. | 245 | /* For each registered chip, we need to keep some data in memory. |
| @@ -964,6 +968,7 @@ static int __init it87_find(unsigned short *address, | |||
| 964 | { | 968 | { |
| 965 | int err = -ENODEV; | 969 | int err = -ENODEV; |
| 966 | u16 chip_type; | 970 | u16 chip_type; |
| 971 | const char *board_vendor, *board_name; | ||
| 967 | 972 | ||
| 968 | superio_enter(); | 973 | superio_enter(); |
| 969 | chip_type = force_id ? force_id : superio_inw(DEVID); | 974 | chip_type = force_id ? force_id : superio_inw(DEVID); |
| @@ -1022,6 +1027,24 @@ static int __init it87_find(unsigned short *address, | |||
| 1022 | pr_info("it87: in7 is VCCH (+5V Stand-By)\n"); | 1027 | pr_info("it87: in7 is VCCH (+5V Stand-By)\n"); |
| 1023 | } | 1028 | } |
| 1024 | 1029 | ||
| 1030 | /* Disable specific features based on DMI strings */ | ||
| 1031 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
| 1032 | board_name = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 1033 | if (board_vendor && board_name) { | ||
| 1034 | if (strcmp(board_vendor, "nVIDIA") == 0 | ||
| 1035 | && strcmp(board_name, "FN68PT") == 0) { | ||
| 1036 | /* On the Shuttle SN68PT, FAN_CTL2 is apparently not | ||
| 1037 | connected to a fan, but to something else. One user | ||
| 1038 | has reported instant system power-off when changing | ||
| 1039 | the PWM2 duty cycle, so we disable it. | ||
| 1040 | I use the board name string as the trigger in case | ||
| 1041 | the same board is ever used in other systems. */ | ||
| 1042 | pr_info("it87: Disabling pwm2 due to " | ||
| 1043 | "hardware constraints\n"); | ||
| 1044 | sio_data->skip_pwm = (1 << 1); | ||
| 1045 | } | ||
| 1046 | } | ||
| 1047 | |||
| 1025 | exit: | 1048 | exit: |
| 1026 | superio_exit(); | 1049 | superio_exit(); |
| 1027 | return err; | 1050 | return err; |
| @@ -1168,25 +1191,33 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
| 1168 | } | 1191 | } |
| 1169 | 1192 | ||
| 1170 | if (enable_pwm_interface) { | 1193 | if (enable_pwm_interface) { |
| 1171 | if ((err = device_create_file(dev, | 1194 | if (!(sio_data->skip_pwm & (1 << 0))) { |
| 1172 | &sensor_dev_attr_pwm1_enable.dev_attr)) | 1195 | if ((err = device_create_file(dev, |
| 1173 | || (err = device_create_file(dev, | 1196 | &sensor_dev_attr_pwm1_enable.dev_attr)) |
| 1174 | &sensor_dev_attr_pwm2_enable.dev_attr)) | 1197 | || (err = device_create_file(dev, |
| 1175 | || (err = device_create_file(dev, | 1198 | &sensor_dev_attr_pwm1.dev_attr)) |
| 1176 | &sensor_dev_attr_pwm3_enable.dev_attr)) | 1199 | || (err = device_create_file(dev, |
| 1177 | || (err = device_create_file(dev, | 1200 | &dev_attr_pwm1_freq))) |
| 1178 | &sensor_dev_attr_pwm1.dev_attr)) | 1201 | goto ERROR4; |
| 1179 | || (err = device_create_file(dev, | 1202 | } |
| 1180 | &sensor_dev_attr_pwm2.dev_attr)) | 1203 | if (!(sio_data->skip_pwm & (1 << 1))) { |
| 1181 | || (err = device_create_file(dev, | 1204 | if ((err = device_create_file(dev, |
| 1182 | &sensor_dev_attr_pwm3.dev_attr)) | 1205 | &sensor_dev_attr_pwm2_enable.dev_attr)) |
| 1183 | || (err = device_create_file(dev, | 1206 | || (err = device_create_file(dev, |
| 1184 | &dev_attr_pwm1_freq)) | 1207 | &sensor_dev_attr_pwm2.dev_attr)) |
| 1185 | || (err = device_create_file(dev, | 1208 | || (err = device_create_file(dev, |
| 1186 | &dev_attr_pwm2_freq)) | 1209 | &dev_attr_pwm2_freq))) |
| 1187 | || (err = device_create_file(dev, | 1210 | goto ERROR4; |
| 1188 | &dev_attr_pwm3_freq))) | 1211 | } |
| 1189 | goto ERROR4; | 1212 | if (!(sio_data->skip_pwm & (1 << 2))) { |
| 1213 | if ((err = device_create_file(dev, | ||
| 1214 | &sensor_dev_attr_pwm3_enable.dev_attr)) | ||
| 1215 | || (err = device_create_file(dev, | ||
| 1216 | &sensor_dev_attr_pwm3.dev_attr)) | ||
| 1217 | || (err = device_create_file(dev, | ||
| 1218 | &dev_attr_pwm3_freq))) | ||
| 1219 | goto ERROR4; | ||
| 1220 | } | ||
| 1190 | } | 1221 | } |
| 1191 | 1222 | ||
| 1192 | if (data->type == it8712 || data->type == it8716 | 1223 | if (data->type == it8712 || data->type == it8716 |
| @@ -1546,6 +1577,7 @@ static int __init sm_it87_init(void) | |||
| 1546 | unsigned short isa_address=0; | 1577 | unsigned short isa_address=0; |
| 1547 | struct it87_sio_data sio_data; | 1578 | struct it87_sio_data sio_data; |
| 1548 | 1579 | ||
| 1580 | memset(&sio_data, 0, sizeof(struct it87_sio_data)); | ||
| 1549 | err = it87_find(&isa_address, &sio_data); | 1581 | err = it87_find(&isa_address, &sio_data); |
| 1550 | if (err) | 1582 | if (err) |
| 1551 | return err; | 1583 | return err; |
