aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/fschmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/fschmd.c')
-rw-r--r--drivers/hwmon/fschmd.c82
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;
56module_param(nowayout, int, 0); 56module_param(nowayout, int, 0);
57MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 57MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
58 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 58 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
59I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl); 59
60enum 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
222static int fschmd_probe(struct i2c_client *client, 223static int fschmd_probe(struct i2c_client *client,
223 const struct i2c_device_id *id); 224 const struct i2c_device_id *id);
224static int fschmd_detect(struct i2c_client *client, int kind, 225static int fschmd_detect(struct i2c_client *client,
225 struct i2c_board_info *info); 226 struct i2c_board_info *info);
226static int fschmd_remove(struct i2c_client *client); 227static int fschmd_remove(struct i2c_client *client);
227static struct fschmd_data *fschmd_update_device(struct device *dev); 228static 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:
767static int watchdog_open(struct inode *inode, struct file *filp) 767static 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
1003static int fschmd_detect(struct i2c_client *client, int kind, 1006static 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,