diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hwmon/fschmd.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/fschmd.c')
-rw-r--r-- | drivers/hwmon/fschmd.c | 235 |
1 files changed, 90 insertions, 145 deletions
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index 519ce8b9c14..aa6d8b686f8 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* fschmd.c |
2 | * fschmd.c | ||
3 | * | 2 | * |
4 | * Copyright (C) 2007 - 2009 Hans de Goede <hdegoede@redhat.com> | 3 | * Copyright (C) 2007 - 2009 Hans de Goede <hdegoede@redhat.com> |
5 | * | 4 | * |
@@ -53,8 +52,8 @@ | |||
53 | static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; | 52 | static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; |
54 | 53 | ||
55 | /* Insmod parameters */ | 54 | /* Insmod parameters */ |
56 | static bool nowayout = WATCHDOG_NOWAYOUT; | 55 | static int nowayout = WATCHDOG_NOWAYOUT; |
57 | module_param(nowayout, bool, 0); | 56 | module_param(nowayout, int, 0); |
58 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | 57 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
59 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 58 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
60 | 59 | ||
@@ -77,12 +76,12 @@ enum chips { fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl }; | |||
77 | #define FSCHMD_CONTROL_ALERT_LED 0x01 | 76 | #define FSCHMD_CONTROL_ALERT_LED 0x01 |
78 | 77 | ||
79 | /* watchdog */ | 78 | /* watchdog */ |
80 | static const u8 FSCHMD_REG_WDOG_CONTROL[7] = { | 79 | static const u8 FSCHMD_REG_WDOG_CONTROL[7] = |
81 | 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 }; | 80 | { 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 }; |
82 | static const u8 FSCHMD_REG_WDOG_STATE[7] = { | 81 | static const u8 FSCHMD_REG_WDOG_STATE[7] = |
83 | 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 }; | 82 | { 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 }; |
84 | static const u8 FSCHMD_REG_WDOG_PRESET[7] = { | 83 | static const u8 FSCHMD_REG_WDOG_PRESET[7] = |
85 | 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a }; | 84 | { 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a }; |
86 | 85 | ||
87 | #define FSCHMD_WDOG_CONTROL_TRIGGER 0x10 | 86 | #define FSCHMD_WDOG_CONTROL_TRIGGER 0x10 |
88 | #define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */ | 87 | #define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */ |
@@ -104,12 +103,10 @@ static const u8 FSCHMD_REG_VOLT[7][6] = { | |||
104 | 103 | ||
105 | static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 }; | 104 | static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 }; |
106 | 105 | ||
107 | /* | 106 | /* minimum pwm at which the fan is driven (pwm can by increased depending on |
108 | * minimum pwm at which the fan is driven (pwm can by increased depending on | 107 | the temp. Notice that for the scy some fans share there minimum speed. |
109 | * the temp. Notice that for the scy some fans share there minimum speed. | 108 | Also notice that with the scy the sensor order is different than with the |
110 | * Also notice that with the scy the sensor order is different than with the | 109 | other chips, this order was in the 2.4 driver and kept for consistency. */ |
111 | * other chips, this order was in the 2.4 driver and kept for consistency. | ||
112 | */ | ||
113 | static const u8 FSCHMD_REG_FAN_MIN[7][7] = { | 110 | static const u8 FSCHMD_REG_FAN_MIN[7][7] = { |
114 | { 0x55, 0x65 }, /* pos */ | 111 | { 0x55, 0x65 }, /* pos */ |
115 | { 0x55, 0x65, 0xb5 }, /* her */ | 112 | { 0x55, 0x65, 0xb5 }, /* her */ |
@@ -185,13 +182,11 @@ static const u8 FSCHMD_REG_TEMP_STATE[7][11] = { | |||
185 | 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 }, | 182 | 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 }, |
186 | }; | 183 | }; |
187 | 184 | ||
188 | /* | 185 | /* temperature high limit registers, FSC does not document these. Proven to be |
189 | * temperature high limit registers, FSC does not document these. Proven to be | 186 | there with field testing on the fscher and fschrc, already supported / used |
190 | * there with field testing on the fscher and fschrc, already supported / used | 187 | in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers |
191 | * in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers | 188 | at these addresses, but doesn't want to confirm they are the same as with |
192 | * at these addresses, but doesn't want to confirm they are the same as with | 189 | the fscher?? */ |
193 | * the fscher?? | ||
194 | */ | ||
195 | static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = { | 190 | static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = { |
196 | { 0, 0, 0 }, /* pos */ | 191 | { 0, 0, 0 }, /* pos */ |
197 | { 0x76, 0x86, 0x96 }, /* her */ | 192 | { 0x76, 0x86, 0x96 }, /* her */ |
@@ -203,15 +198,13 @@ static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = { | |||
203 | 0xba, 0xca, 0xda, 0xea, 0xfa }, | 198 | 0xba, 0xca, 0xda, 0xea, 0xfa }, |
204 | }; | 199 | }; |
205 | 200 | ||
206 | /* | 201 | /* These were found through experimenting with an fscher, currently they are |
207 | * These were found through experimenting with an fscher, currently they are | 202 | not used, but we keep them around for future reference. |
208 | * not used, but we keep them around for future reference. | 203 | On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc), |
209 | * On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc), | 204 | AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence |
210 | * AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence | 205 | the fan speed. |
211 | * the fan speed. | 206 | static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; |
212 | * static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; | 207 | static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */ |
213 | * static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; | ||
214 | */ | ||
215 | 208 | ||
216 | static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 }; | 209 | static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 }; |
217 | 210 | ||
@@ -297,30 +290,24 @@ struct fschmd_data { | |||
297 | u8 fan_ripple[7]; /* divider for rps */ | 290 | u8 fan_ripple[7]; /* divider for rps */ |
298 | }; | 291 | }; |
299 | 292 | ||
300 | /* | 293 | /* Global variables to hold information read from special DMI tables, which are |
301 | * Global variables to hold information read from special DMI tables, which are | 294 | available on FSC machines with an fscher or later chip. There is no need to |
302 | * available on FSC machines with an fscher or later chip. There is no need to | 295 | protect these with a lock as they are only modified from our attach function |
303 | * protect these with a lock as they are only modified from our attach function | 296 | which always gets called with the i2c-core lock held and never accessed |
304 | * which always gets called with the i2c-core lock held and never accessed | 297 | before the attach function is done with them. */ |
305 | * before the attach function is done with them. | ||
306 | */ | ||
307 | static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 }; | 298 | static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 }; |
308 | static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 }; | 299 | static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 }; |
309 | static int dmi_vref = -1; | 300 | static int dmi_vref = -1; |
310 | 301 | ||
311 | /* | 302 | /* Somewhat ugly :( global data pointer list with all fschmd devices, so that |
312 | * Somewhat ugly :( global data pointer list with all fschmd devices, so that | 303 | we can find our device data as when using misc_register there is no other |
313 | * we can find our device data as when using misc_register there is no other | 304 | method to get to ones device data from the open fop. */ |
314 | * method to get to ones device data from the open fop. | ||
315 | */ | ||
316 | static LIST_HEAD(watchdog_data_list); | 305 | static LIST_HEAD(watchdog_data_list); |
317 | /* Note this lock not only protect list access, but also data.kref access */ | 306 | /* Note this lock not only protect list access, but also data.kref access */ |
318 | static DEFINE_MUTEX(watchdog_data_mutex); | 307 | static DEFINE_MUTEX(watchdog_data_mutex); |
319 | 308 | ||
320 | /* | 309 | /* Release our data struct when we're detached from the i2c client *and* all |
321 | * Release our data struct when we're detached from the i2c client *and* all | 310 | references to our watchdog device are released */ |
322 | * references to our watchdog device are released | ||
323 | */ | ||
324 | static void fschmd_release_resources(struct kref *ref) | 311 | static void fschmd_release_resources(struct kref *ref) |
325 | { | 312 | { |
326 | struct fschmd_data *data = container_of(ref, struct fschmd_data, kref); | 313 | struct fschmd_data *data = container_of(ref, struct fschmd_data, kref); |
@@ -372,14 +359,9 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute | |||
372 | { | 359 | { |
373 | int index = to_sensor_dev_attr(devattr)->index; | 360 | int index = to_sensor_dev_attr(devattr)->index; |
374 | struct fschmd_data *data = dev_get_drvdata(dev); | 361 | struct fschmd_data *data = dev_get_drvdata(dev); |
375 | long v; | 362 | long v = simple_strtol(buf, NULL, 10) / 1000; |
376 | int err; | ||
377 | 363 | ||
378 | err = kstrtol(buf, 10, &v); | 364 | v = SENSORS_LIMIT(v, -128, 127) + 128; |
379 | if (err) | ||
380 | return err; | ||
381 | |||
382 | v = SENSORS_LIMIT(v / 1000, -128, 127) + 128; | ||
383 | 365 | ||
384 | mutex_lock(&data->update_lock); | 366 | mutex_lock(&data->update_lock); |
385 | i2c_smbus_write_byte_data(to_i2c_client(dev), | 367 | i2c_smbus_write_byte_data(to_i2c_client(dev), |
@@ -445,23 +427,12 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute | |||
445 | int index = to_sensor_dev_attr(devattr)->index; | 427 | int index = to_sensor_dev_attr(devattr)->index; |
446 | struct fschmd_data *data = dev_get_drvdata(dev); | 428 | struct fschmd_data *data = dev_get_drvdata(dev); |
447 | /* supported values: 2, 4, 8 */ | 429 | /* supported values: 2, 4, 8 */ |
448 | unsigned long v; | 430 | unsigned long v = simple_strtoul(buf, NULL, 10); |
449 | int err; | ||
450 | |||
451 | err = kstrtoul(buf, 10, &v); | ||
452 | if (err) | ||
453 | return err; | ||
454 | 431 | ||
455 | switch (v) { | 432 | switch (v) { |
456 | case 2: | 433 | case 2: v = 1; break; |
457 | v = 1; | 434 | case 4: v = 2; break; |
458 | break; | 435 | case 8: v = 3; break; |
459 | case 4: | ||
460 | v = 2; | ||
461 | break; | ||
462 | case 8: | ||
463 | v = 3; | ||
464 | break; | ||
465 | default: | 436 | default: |
466 | dev_err(dev, "fan_div value %lu not supported. " | 437 | dev_err(dev, "fan_div value %lu not supported. " |
467 | "Choose one of 2, 4 or 8!\n", v); | 438 | "Choose one of 2, 4 or 8!\n", v); |
@@ -531,12 +502,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev, | |||
531 | { | 502 | { |
532 | int index = to_sensor_dev_attr(devattr)->index; | 503 | int index = to_sensor_dev_attr(devattr)->index; |
533 | struct fschmd_data *data = dev_get_drvdata(dev); | 504 | struct fschmd_data *data = dev_get_drvdata(dev); |
534 | unsigned long v; | 505 | unsigned long v = simple_strtoul(buf, NULL, 10); |
535 | int err; | ||
536 | |||
537 | err = kstrtoul(buf, 10, &v); | ||
538 | if (err) | ||
539 | return err; | ||
540 | 506 | ||
541 | /* 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% */ |
542 | if (v || data->kind == fscsyl) { | 508 | if (v || data->kind == fscsyl) { |
@@ -556,10 +522,8 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev, | |||
556 | } | 522 | } |
557 | 523 | ||
558 | 524 | ||
559 | /* | 525 | /* The FSC hwmon family has the ability to force an attached alert led to flash |
560 | * The FSC hwmon family has the ability to force an attached alert led to flash | 526 | from software, we export this as an alert_led sysfs attr */ |
561 | * from software, we export this as an alert_led sysfs attr | ||
562 | */ | ||
563 | static ssize_t show_alert_led(struct device *dev, | 527 | static ssize_t show_alert_led(struct device *dev, |
564 | struct device_attribute *devattr, char *buf) | 528 | struct device_attribute *devattr, char *buf) |
565 | { | 529 | { |
@@ -576,12 +540,7 @@ static ssize_t store_alert_led(struct device *dev, | |||
576 | { | 540 | { |
577 | u8 reg; | 541 | u8 reg; |
578 | struct fschmd_data *data = dev_get_drvdata(dev); | 542 | struct fschmd_data *data = dev_get_drvdata(dev); |
579 | unsigned long v; | 543 | unsigned long v = simple_strtoul(buf, NULL, 10); |
580 | int err; | ||
581 | |||
582 | err = kstrtoul(buf, 10, &v); | ||
583 | if (err) | ||
584 | return err; | ||
585 | 544 | ||
586 | mutex_lock(&data->update_lock); | 545 | mutex_lock(&data->update_lock); |
587 | 546 | ||
@@ -795,10 +754,8 @@ static int watchdog_stop(struct fschmd_data *data) | |||
795 | } | 754 | } |
796 | 755 | ||
797 | data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED; | 756 | data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED; |
798 | /* | 757 | /* Don't store the stop flag in our watchdog control register copy, as |
799 | * Don't store the stop flag in our watchdog control register copy, as | 758 | its a write only bit (read always returns 0) */ |
800 | * its a write only bit (read always returns 0) | ||
801 | */ | ||
802 | i2c_smbus_write_byte_data(data->client, | 759 | i2c_smbus_write_byte_data(data->client, |
803 | FSCHMD_REG_WDOG_CONTROL[data->kind], | 760 | FSCHMD_REG_WDOG_CONTROL[data->kind], |
804 | data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP); | 761 | data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP); |
@@ -812,12 +769,10 @@ static int watchdog_open(struct inode *inode, struct file *filp) | |||
812 | struct fschmd_data *pos, *data = NULL; | 769 | struct fschmd_data *pos, *data = NULL; |
813 | int watchdog_is_open; | 770 | int watchdog_is_open; |
814 | 771 | ||
815 | /* | 772 | /* We get called from drivers/char/misc.c with misc_mtx hold, and we |
816 | * We get called from drivers/char/misc.c with misc_mtx hold, and we | 773 | call misc_register() from fschmd_probe() with watchdog_data_mutex |
817 | * call misc_register() from fschmd_probe() with watchdog_data_mutex | 774 | hold, as misc_register() takes the misc_mtx lock, this is a possible |
818 | * hold, as misc_register() takes the misc_mtx lock, this is a possible | 775 | deadlock, so we use mutex_trylock here. */ |
819 | * deadlock, so we use mutex_trylock here. | ||
820 | */ | ||
821 | if (!mutex_trylock(&watchdog_data_mutex)) | 776 | if (!mutex_trylock(&watchdog_data_mutex)) |
822 | return -ERESTARTSYS; | 777 | return -ERESTARTSYS; |
823 | list_for_each_entry(pos, &watchdog_data_list, list) { | 778 | list_for_each_entry(pos, &watchdog_data_list, list) { |
@@ -892,8 +847,7 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf, | |||
892 | return count; | 847 | return count; |
893 | } | 848 | } |
894 | 849 | ||
895 | static long watchdog_ioctl(struct file *filp, unsigned int cmd, | 850 | static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
896 | unsigned long arg) | ||
897 | { | 851 | { |
898 | struct watchdog_info ident = { | 852 | struct watchdog_info ident = { |
899 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | | 853 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
@@ -976,38 +930,30 @@ static const struct file_operations watchdog_fops = { | |||
976 | * Detect, register, unregister and update device functions | 930 | * Detect, register, unregister and update device functions |
977 | */ | 931 | */ |
978 | 932 | ||
979 | /* | 933 | /* DMI decode routine to read voltage scaling factors from special DMI tables, |
980 | * DMI decode routine to read voltage scaling factors from special DMI tables, | 934 | which are available on FSC machines with an fscher or later chip. */ |
981 | * which are available on FSC machines with an fscher or later chip. | ||
982 | */ | ||
983 | static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) | 935 | static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) |
984 | { | 936 | { |
985 | int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0; | 937 | int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0; |
986 | 938 | ||
987 | /* | 939 | /* dmi code ugliness, we get passed the address of the contents of |
988 | * dmi code ugliness, we get passed the address of the contents of | 940 | a complete DMI record, but in the form of a dmi_header pointer, in |
989 | * a complete DMI record, but in the form of a dmi_header pointer, in | 941 | reality this address holds header->length bytes of which the header |
990 | * reality this address holds header->length bytes of which the header | 942 | are the first 4 bytes */ |
991 | * are the first 4 bytes | ||
992 | */ | ||
993 | u8 *dmi_data = (u8 *)header; | 943 | u8 *dmi_data = (u8 *)header; |
994 | 944 | ||
995 | /* We are looking for OEM-specific type 185 */ | 945 | /* We are looking for OEM-specific type 185 */ |
996 | if (header->type != 185) | 946 | if (header->type != 185) |
997 | return; | 947 | return; |
998 | 948 | ||
999 | /* | 949 | /* we are looking for what Siemens calls "subtype" 19, the subtype |
1000 | * we are looking for what Siemens calls "subtype" 19, the subtype | 950 | is stored in byte 5 of the dmi block */ |
1001 | * is stored in byte 5 of the dmi block | ||
1002 | */ | ||
1003 | if (header->length < 5 || dmi_data[4] != 19) | 951 | if (header->length < 5 || dmi_data[4] != 19) |
1004 | return; | 952 | return; |
1005 | 953 | ||
1006 | /* | 954 | /* After the subtype comes 1 unknown byte and then blocks of 5 bytes, |
1007 | * After the subtype comes 1 unknown byte and then blocks of 5 bytes, | 955 | consisting of what Siemens calls an "Entity" number, followed by |
1008 | * consisting of what Siemens calls an "Entity" number, followed by | 956 | 2 16-bit words in LSB first order */ |
1009 | * 2 16-bit words in LSB first order | ||
1010 | */ | ||
1011 | for (i = 6; (i + 4) < header->length; i += 5) { | 957 | for (i = 6; (i + 4) < header->length; i += 5) { |
1012 | /* entity 1 - 3: voltage multiplier and offset */ | 958 | /* entity 1 - 3: voltage multiplier and offset */ |
1013 | if (dmi_data[i] >= 1 && dmi_data[i] <= 3) { | 959 | if (dmi_data[i] >= 1 && dmi_data[i] <= 3) { |
@@ -1042,11 +988,9 @@ static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy) | |||
1042 | dmi_mult[i] = mult[i] * 10; | 988 | dmi_mult[i] = mult[i] * 10; |
1043 | dmi_offset[i] = offset[i] * 10; | 989 | dmi_offset[i] = offset[i] * 10; |
1044 | } | 990 | } |
1045 | /* | 991 | /* According to the docs there should be separate dmi entries |
1046 | * According to the docs there should be separate dmi entries | 992 | for the mult's and offsets of in3-5 of the syl, but on |
1047 | * for the mult's and offsets of in3-5 of the syl, but on | 993 | my test machine these are not present */ |
1048 | * my test machine these are not present | ||
1049 | */ | ||
1050 | dmi_mult[3] = dmi_mult[2]; | 994 | dmi_mult[3] = dmi_mult[2]; |
1051 | dmi_mult[4] = dmi_mult[1]; | 995 | dmi_mult[4] = dmi_mult[1]; |
1052 | dmi_mult[5] = dmi_mult[2]; | 996 | dmi_mult[5] = dmi_mult[2]; |
@@ -1114,19 +1058,15 @@ static int fschmd_probe(struct i2c_client *client, | |||
1114 | mutex_init(&data->watchdog_lock); | 1058 | mutex_init(&data->watchdog_lock); |
1115 | INIT_LIST_HEAD(&data->list); | 1059 | INIT_LIST_HEAD(&data->list); |
1116 | kref_init(&data->kref); | 1060 | kref_init(&data->kref); |
1117 | /* | 1061 | /* Store client pointer in our data struct for watchdog usage |
1118 | * Store client pointer in our data struct for watchdog usage | 1062 | (where the client is found through a data ptr instead of the |
1119 | * (where the client is found through a data ptr instead of the | 1063 | otherway around) */ |
1120 | * otherway around) | ||
1121 | */ | ||
1122 | data->client = client; | 1064 | data->client = client; |
1123 | data->kind = kind; | 1065 | data->kind = kind; |
1124 | 1066 | ||
1125 | if (kind == fscpos) { | 1067 | if (kind == fscpos) { |
1126 | /* | 1068 | /* The Poseidon has hardwired temp limits, fill these |
1127 | * The Poseidon has hardwired temp limits, fill these | 1069 | in for the alarm resetting code */ |
1128 | * in for the alarm resetting code | ||
1129 | */ | ||
1130 | data->temp_max[0] = 70 + 128; | 1070 | data->temp_max[0] = 70 + 128; |
1131 | data->temp_max[1] = 50 + 128; | 1071 | data->temp_max[1] = 50 + 128; |
1132 | data->temp_max[2] = 50 + 128; | 1072 | data->temp_max[2] = 50 + 128; |
@@ -1217,11 +1157,9 @@ static int fschmd_probe(struct i2c_client *client, | |||
1217 | goto exit_detach; | 1157 | goto exit_detach; |
1218 | } | 1158 | } |
1219 | 1159 | ||
1220 | /* | 1160 | /* We take the data_mutex lock early so that watchdog_open() cannot |
1221 | * We take the data_mutex lock early so that watchdog_open() cannot | 1161 | run when misc_register() has completed, but we've not yet added |
1222 | * run when misc_register() has completed, but we've not yet added | 1162 | our data to the watchdog_data_list (and set the default timeout) */ |
1223 | * our data to the watchdog_data_list (and set the default timeout) | ||
1224 | */ | ||
1225 | mutex_lock(&watchdog_data_mutex); | 1163 | mutex_lock(&watchdog_data_mutex); |
1226 | for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) { | 1164 | for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) { |
1227 | /* Register our watchdog part */ | 1165 | /* Register our watchdog part */ |
@@ -1287,10 +1225,8 @@ static int fschmd_remove(struct i2c_client *client) | |||
1287 | mutex_unlock(&data->watchdog_lock); | 1225 | mutex_unlock(&data->watchdog_lock); |
1288 | } | 1226 | } |
1289 | 1227 | ||
1290 | /* | 1228 | /* Check if registered in case we're called from fschmd_detect |
1291 | * Check if registered in case we're called from fschmd_detect | 1229 | to cleanup after an error */ |
1292 | * to cleanup after an error | ||
1293 | */ | ||
1294 | if (data->hwmon_dev) | 1230 | if (data->hwmon_dev) |
1295 | hwmon_device_unregister(data->hwmon_dev); | 1231 | hwmon_device_unregister(data->hwmon_dev); |
1296 | 1232 | ||
@@ -1333,10 +1269,8 @@ static struct fschmd_data *fschmd_update_device(struct device *dev) | |||
1333 | client, | 1269 | client, |
1334 | FSCHMD_REG_TEMP_LIMIT[data->kind][i]); | 1270 | FSCHMD_REG_TEMP_LIMIT[data->kind][i]); |
1335 | 1271 | ||
1336 | /* | 1272 | /* reset alarm if the alarm condition is gone, |
1337 | * reset alarm if the alarm condition is gone, | 1273 | the chip doesn't do this itself */ |
1338 | * the chip doesn't do this itself | ||
1339 | */ | ||
1340 | if ((data->temp_status[i] & FSCHMD_TEMP_ALARM_MASK) == | 1274 | if ((data->temp_status[i] & FSCHMD_TEMP_ALARM_MASK) == |
1341 | FSCHMD_TEMP_ALARM_MASK && | 1275 | FSCHMD_TEMP_ALARM_MASK && |
1342 | data->temp_act[i] < data->temp_max[i]) | 1276 | data->temp_act[i] < data->temp_max[i]) |
@@ -1380,9 +1314,20 @@ static struct fschmd_data *fschmd_update_device(struct device *dev) | |||
1380 | return data; | 1314 | return data; |
1381 | } | 1315 | } |
1382 | 1316 | ||
1383 | module_i2c_driver(fschmd_driver); | 1317 | static int __init fschmd_init(void) |
1318 | { | ||
1319 | return i2c_add_driver(&fschmd_driver); | ||
1320 | } | ||
1321 | |||
1322 | static void __exit fschmd_exit(void) | ||
1323 | { | ||
1324 | i2c_del_driver(&fschmd_driver); | ||
1325 | } | ||
1384 | 1326 | ||
1385 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | 1327 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
1386 | MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades " | 1328 | MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades " |
1387 | "and Syleus driver"); | 1329 | "and Syleus driver"); |
1388 | MODULE_LICENSE("GPL"); | 1330 | MODULE_LICENSE("GPL"); |
1331 | |||
1332 | module_init(fschmd_init); | ||
1333 | module_exit(fschmd_exit); | ||