diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/hwmon/fschmd.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/hwmon/fschmd.c')
-rw-r--r-- | drivers/hwmon/fschmd.c | 82 |
1 files changed, 39 insertions, 43 deletions
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index da1b1f9488af..0627f7a5b9b8 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c | |||
@@ -56,7 +56,8 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
56 | module_param(nowayout, int, 0); | 56 | module_param(nowayout, int, 0); |
57 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | 57 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
58 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 58 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
59 | I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl); | 59 | |
60 | enum chips { fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl }; | ||
60 | 61 | ||
61 | /* | 62 | /* |
62 | * The FSCHMD registers and other defines | 63 | * The FSCHMD registers and other defines |
@@ -221,7 +222,7 @@ static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 }; | |||
221 | 222 | ||
222 | static int fschmd_probe(struct i2c_client *client, | 223 | static int fschmd_probe(struct i2c_client *client, |
223 | const struct i2c_device_id *id); | 224 | const struct i2c_device_id *id); |
224 | static int fschmd_detect(struct i2c_client *client, int kind, | 225 | static int fschmd_detect(struct i2c_client *client, |
225 | struct i2c_board_info *info); | 226 | struct i2c_board_info *info); |
226 | static int fschmd_remove(struct i2c_client *client); | 227 | static int fschmd_remove(struct i2c_client *client); |
227 | static struct fschmd_data *fschmd_update_device(struct device *dev); | 228 | static struct fschmd_data *fschmd_update_device(struct device *dev); |
@@ -251,7 +252,7 @@ static struct i2c_driver fschmd_driver = { | |||
251 | .remove = fschmd_remove, | 252 | .remove = fschmd_remove, |
252 | .id_table = fschmd_id, | 253 | .id_table = fschmd_id, |
253 | .detect = fschmd_detect, | 254 | .detect = fschmd_detect, |
254 | .address_data = &addr_data, | 255 | .address_list = normal_i2c, |
255 | }; | 256 | }; |
256 | 257 | ||
257 | /* | 258 | /* |
@@ -266,7 +267,7 @@ struct fschmd_data { | |||
266 | struct list_head list; /* member of the watchdog_data_list */ | 267 | struct list_head list; /* member of the watchdog_data_list */ |
267 | struct kref kref; | 268 | struct kref kref; |
268 | struct miscdevice watchdog_miscdev; | 269 | struct miscdevice watchdog_miscdev; |
269 | int kind; | 270 | enum chips kind; |
270 | unsigned long watchdog_is_open; | 271 | unsigned long watchdog_is_open; |
271 | char watchdog_expect_close; | 272 | char watchdog_expect_close; |
272 | char watchdog_name[10]; /* must be unique to avoid sysfs conflict */ | 273 | char watchdog_name[10]; /* must be unique to avoid sysfs conflict */ |
@@ -324,8 +325,7 @@ static ssize_t show_in_value(struct device *dev, | |||
324 | int index = to_sensor_dev_attr(devattr)->index; | 325 | int index = to_sensor_dev_attr(devattr)->index; |
325 | struct fschmd_data *data = fschmd_update_device(dev); | 326 | struct fschmd_data *data = fschmd_update_device(dev); |
326 | 327 | ||
327 | /* fscher / fschrc - 1 as data->kind is an array index, not a chips */ | 328 | if (data->kind == fscher || data->kind >= fschrc) |
328 | if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1)) | ||
329 | return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref * | 329 | return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref * |
330 | dmi_mult[index]) / 255 + dmi_offset[index]); | 330 | dmi_mult[index]) / 255 + dmi_offset[index]); |
331 | else | 331 | else |
@@ -491,7 +491,7 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev, | |||
491 | int val = data->fan_min[index]; | 491 | int val = data->fan_min[index]; |
492 | 492 | ||
493 | /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */ | 493 | /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */ |
494 | if (val || data->kind == fscsyl - 1) | 494 | if (val || data->kind == fscsyl) |
495 | val = val / 2 + 128; | 495 | val = val / 2 + 128; |
496 | 496 | ||
497 | return sprintf(buf, "%d\n", val); | 497 | return sprintf(buf, "%d\n", val); |
@@ -505,7 +505,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev, | |||
505 | unsigned long v = simple_strtoul(buf, NULL, 10); | 505 | unsigned long v = simple_strtoul(buf, NULL, 10); |
506 | 506 | ||
507 | /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */ | 507 | /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */ |
508 | if (v || data->kind == fscsyl - 1) { | 508 | if (v || data->kind == fscsyl) { |
509 | v = SENSORS_LIMIT(v, 128, 255); | 509 | v = SENSORS_LIMIT(v, 128, 255); |
510 | v = (v - 128) * 2 + 1; | 510 | v = (v - 128) * 2 + 1; |
511 | } | 511 | } |
@@ -767,6 +767,7 @@ leave: | |||
767 | static int watchdog_open(struct inode *inode, struct file *filp) | 767 | static int watchdog_open(struct inode *inode, struct file *filp) |
768 | { | 768 | { |
769 | struct fschmd_data *pos, *data = NULL; | 769 | struct fschmd_data *pos, *data = NULL; |
770 | int watchdog_is_open; | ||
770 | 771 | ||
771 | /* We get called from drivers/char/misc.c with misc_mtx hold, and we | 772 | /* We get called from drivers/char/misc.c with misc_mtx hold, and we |
772 | call misc_register() from fschmd_probe() with watchdog_data_mutex | 773 | call misc_register() from fschmd_probe() with watchdog_data_mutex |
@@ -781,10 +782,12 @@ static int watchdog_open(struct inode *inode, struct file *filp) | |||
781 | } | 782 | } |
782 | } | 783 | } |
783 | /* Note we can never not have found data, so we don't check for this */ | 784 | /* Note we can never not have found data, so we don't check for this */ |
784 | kref_get(&data->kref); | 785 | watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open); |
786 | if (!watchdog_is_open) | ||
787 | kref_get(&data->kref); | ||
785 | mutex_unlock(&watchdog_data_mutex); | 788 | mutex_unlock(&watchdog_data_mutex); |
786 | 789 | ||
787 | if (test_and_set_bit(0, &data->watchdog_is_open)) | 790 | if (watchdog_is_open) |
788 | return -EBUSY; | 791 | return -EBUSY; |
789 | 792 | ||
790 | /* Start the watchdog */ | 793 | /* Start the watchdog */ |
@@ -1000,45 +1003,40 @@ static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) | |||
1000 | } | 1003 | } |
1001 | } | 1004 | } |
1002 | 1005 | ||
1003 | static int fschmd_detect(struct i2c_client *client, int kind, | 1006 | static int fschmd_detect(struct i2c_client *client, |
1004 | struct i2c_board_info *info) | 1007 | struct i2c_board_info *info) |
1005 | { | 1008 | { |
1009 | enum chips kind; | ||
1006 | struct i2c_adapter *adapter = client->adapter; | 1010 | struct i2c_adapter *adapter = client->adapter; |
1011 | char id[4]; | ||
1007 | 1012 | ||
1008 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1013 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
1009 | return -ENODEV; | 1014 | return -ENODEV; |
1010 | 1015 | ||
1011 | /* Detect & Identify the chip */ | 1016 | /* Detect & Identify the chip */ |
1012 | if (kind <= 0) { | 1017 | id[0] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_0); |
1013 | char id[4]; | 1018 | id[1] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_1); |
1014 | 1019 | id[2] = i2c_smbus_read_byte_data(client, FSCHMD_REG_IDENT_2); | |
1015 | id[0] = i2c_smbus_read_byte_data(client, | 1020 | id[3] = '\0'; |
1016 | FSCHMD_REG_IDENT_0); | 1021 | |
1017 | id[1] = i2c_smbus_read_byte_data(client, | 1022 | if (!strcmp(id, "PEG")) |
1018 | FSCHMD_REG_IDENT_1); | 1023 | kind = fscpos; |
1019 | id[2] = i2c_smbus_read_byte_data(client, | 1024 | else if (!strcmp(id, "HER")) |
1020 | FSCHMD_REG_IDENT_2); | 1025 | kind = fscher; |
1021 | id[3] = '\0'; | 1026 | else if (!strcmp(id, "SCY")) |
1022 | 1027 | kind = fscscy; | |
1023 | if (!strcmp(id, "PEG")) | 1028 | else if (!strcmp(id, "HRC")) |
1024 | kind = fscpos; | 1029 | kind = fschrc; |
1025 | else if (!strcmp(id, "HER")) | 1030 | else if (!strcmp(id, "HMD")) |
1026 | kind = fscher; | 1031 | kind = fschmd; |
1027 | else if (!strcmp(id, "SCY")) | 1032 | else if (!strcmp(id, "HDS")) |
1028 | kind = fscscy; | 1033 | kind = fschds; |
1029 | else if (!strcmp(id, "HRC")) | 1034 | else if (!strcmp(id, "SYL")) |
1030 | kind = fschrc; | 1035 | kind = fscsyl; |
1031 | else if (!strcmp(id, "HMD")) | 1036 | else |
1032 | kind = fschmd; | 1037 | return -ENODEV; |
1033 | else if (!strcmp(id, "HDS")) | ||
1034 | kind = fschds; | ||
1035 | else if (!strcmp(id, "SYL")) | ||
1036 | kind = fscsyl; | ||
1037 | else | ||
1038 | return -ENODEV; | ||
1039 | } | ||
1040 | 1038 | ||
1041 | strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE); | 1039 | strlcpy(info->type, fschmd_id[kind].name, I2C_NAME_SIZE); |
1042 | 1040 | ||
1043 | return 0; | 1041 | return 0; |
1044 | } | 1042 | } |
@@ -1066,6 +1064,7 @@ static int fschmd_probe(struct i2c_client *client, | |||
1066 | (where the client is found through a data ptr instead of the | 1064 | (where the client is found through a data ptr instead of the |
1067 | otherway around) */ | 1065 | otherway around) */ |
1068 | data->client = client; | 1066 | data->client = client; |
1067 | data->kind = kind; | ||
1069 | 1068 | ||
1070 | if (kind == fscpos) { | 1069 | if (kind == fscpos) { |
1071 | /* The Poseidon has hardwired temp limits, fill these | 1070 | /* The Poseidon has hardwired temp limits, fill these |
@@ -1086,9 +1085,6 @@ static int fschmd_probe(struct i2c_client *client, | |||
1086 | } | 1085 | } |
1087 | } | 1086 | } |
1088 | 1087 | ||
1089 | /* i2c kind goes from 1-6, we want from 0-5 to address arrays */ | ||
1090 | data->kind = kind - 1; | ||
1091 | |||
1092 | /* Read in some never changing registers */ | 1088 | /* Read in some never changing registers */ |
1093 | data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION); | 1089 | data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION); |
1094 | data->global_control = i2c_smbus_read_byte_data(client, | 1090 | data->global_control = i2c_smbus_read_byte_data(client, |