]> git.sur5r.net Git - groeck-it87/blobdiff - it87.c
Add driver removal notice
[groeck-it87] / it87.c
diff --git a/it87.c b/it87.c
index 46544856c591cf07917aa526c96d3d20411b87df..79bf6b14c0696772762cdbd4005c9fa4d7757501 100644 (file)
--- a/it87.c
+++ b/it87.c
@@ -11,6 +11,7 @@
  *  similar parts.  The other devices are supported by different drivers.
  *
  *  Supports: IT8603E  Super I/O chip w/LPC interface
+ *            IT8606E  Super I/O chip w/LPC interface
  *            IT8607E  Super I/O chip w/LPC interface
  *            IT8613E  Super I/O chip w/LPC interface
  *            IT8620E  Super I/O chip w/LPC interface
@@ -30,6 +31,8 @@
  *            IT8726F  Super I/O chip w/LPC interface
  *            IT8728F  Super I/O chip w/LPC interface
  *            IT8732F  Super I/O chip w/LPC interface
+ *            IT8736F  Super I/O chip w/LPC interface
+ *            IT8738E  Super I/O chip w/LPC interface
  *            IT8758E  Super I/O chip w/LPC interface
  *            IT8771E  Super I/O chip w/LPC interface
  *            IT8772E  Super I/O chip w/LPC interface
 #include <linux/acpi.h>
 #include <linux/io.h>
 #include "compat.h"
-#include "version.h"
+
+#ifndef IT87_DRIVER_VERSION
+#define IT87_DRIVER_VERSION    "<not provided>"
+#endif
 
 #define DRVNAME "it87"
 
 enum chips { it87, it8712, it8716, it8718, it8720, it8721, it8728, it8732,
+            it8736, it8738,
             it8771, it8772, it8781, it8782, it8783, it8786, it8790,
-            it8792, it8603, it8607, it8613, it8620, it8622, it8625, it8628,
-            it8655, it8665, it8686 };
+            it8792, it8603, it8606, it8607, it8613, it8620, it8622, it8625,
+            it8628, it8655, it8665, it8686 };
 
 static unsigned short force_id;
-module_param(force_id, ushort, 0);
+module_param(force_id, ushort, 0000);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
 static bool ignore_resource_conflict;
-module_param(ignore_resource_conflict, bool, 0);
+module_param(ignore_resource_conflict, bool, 0000);
 MODULE_PARM_DESC(ignore_resource_conflict, "Ignore ACPI resource conflict");
 
 static bool mmio;
-module_param(mmio, bool, 0);
+module_param(mmio, bool, 0000);
 MODULE_PARM_DESC(mmio, "Use MMIO if available");
 
 static struct platform_device *it87_pdev[2];
@@ -175,6 +182,8 @@ static inline void superio_exit(int ioreg, bool doexit)
 #define IT8726F_DEVID 0x8726
 #define IT8728F_DEVID 0x8728
 #define IT8732F_DEVID 0x8732
+#define IT8736F_DEVID 0x8736
+#define IT8738E_DEVID 0x8738
 #define IT8792E_DEVID 0x8733
 #define IT8771E_DEVID 0x8771
 #define IT8772E_DEVID 0x8772
@@ -184,6 +193,7 @@ static inline void superio_exit(int ioreg, bool doexit)
 #define IT8786E_DEVID 0x8786
 #define IT8790E_DEVID 0x8790
 #define IT8603E_DEVID 0x8603
+#define IT8606E_DEVID 0x8606
 #define IT8607E_DEVID 0x8607
 #define IT8613E_DEVID 0x8613
 #define IT8620E_DEVID 0x8620
@@ -240,11 +250,11 @@ static bool fix_pwm_polarity;
 
 /*----- The IT87 registers -----*/
 
-#define IT87_REG_CONFIG        0x00
+#define IT87_REG_CONFIG                0x00
 
-#define IT87_REG_ALARM1        0x01
-#define IT87_REG_ALARM2        0x02
-#define IT87_REG_ALARM3        0x03
+#define IT87_REG_ALARM1                0x01
+#define IT87_REG_ALARM2                0x02
+#define IT87_REG_ALARM3                0x03
 
 #define IT87_REG_BANK          0x06
 
@@ -252,14 +262,18 @@ static bool fix_pwm_polarity;
  * The IT8718F and IT8720F have the VID value in a different register, in
  * Super-I/O configuration space.
  */
-#define IT87_REG_VID           0x0a
+#define IT87_REG_VID           0x0a
+
+/* Interface Selection register on other chips */
+#define IT87_REG_IFSEL         0x0a
+
 /*
  * The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
  * for fan divisors. Later IT8712F revisions must use 16-bit tachometer
  * mode.
  */
-#define IT87_REG_FAN_DIV       0x0b
-#define IT87_REG_FAN_16BIT     0x0c
+#define IT87_REG_FAN_DIV       0x0b
+#define IT87_REG_FAN_16BIT     0x0c
 
 /*
  * Monitors:
@@ -274,18 +288,19 @@ static const u8 IT87_REG_FANX[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x4d };
 static const u8 IT87_REG_FANX_MIN[] =  { 0x1b, 0x1c, 0x1d, 0x85, 0x87, 0x4f };
 
 static const u8 IT87_REG_FAN_8665[] =  { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x93 };
-static const u8 IT87_REG_FAN_MIN_8665[] =
-                                       0x10, 0x11, 0x12, 0x84, 0x86, 0xb2 };
+static const u8 IT87_REG_FAN_MIN_8665[] = {
+                                       0x10, 0x11, 0x12, 0x84, 0x86, 0xb2 };
 static const u8 IT87_REG_FANX_8665[] = { 0x18, 0x19, 0x1a, 0x81, 0x83, 0x94 };
-static const u8 IT87_REG_FANX_MIN_8665[] =
-                                       0x1b, 0x1c, 0x1d, 0x85, 0x87, 0xb3 };
+static const u8 IT87_REG_FANX_MIN_8665[] = {
+                                       0x1b, 0x1c, 0x1d, 0x85, 0x87, 0xb3 };
 
 static const u8 IT87_REG_TEMP_OFFSET[] = { 0x56, 0x57, 0x59, 0x5a, 0x90, 0x91 };
 
-static const u8 IT87_REG_TEMP_OFFSET_8686[] = { 0x56, 0x57, 0x59, 0x90, 0x91, 0x92 };
+static const u8 IT87_REG_TEMP_OFFSET_8686[] = {
+                                       0x56, 0x57, 0x59, 0x90, 0x91, 0x92 };
 
-#define IT87_REG_FAN_MAIN_CTRL 0x13
-#define IT87_REG_FAN_CTL       0x14
+#define IT87_REG_FAN_MAIN_CTRL 0x13
+#define IT87_REG_FAN_CTL       0x14
 
 static const u8 IT87_REG_PWM[] =       { 0x15, 0x16, 0x17, 0x7f, 0xa7, 0xaf };
 static const u8 IT87_REG_PWM_8665[] =  { 0x15, 0x16, 0x17, 0x1e, 0x1f, 0x92 };
@@ -295,25 +310,25 @@ static const u8 IT87_REG_PWM_DUTY[] =     { 0x63, 0x6b, 0x73, 0x7b, 0xa3, 0xab };
 static const u8 IT87_REG_VIN[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
                                    0x27, 0x28, 0x2f, 0x2c, 0x2d, 0x2e };
 
-#define IT87_REG_TEMP(nr)      (0x29 + (nr))
+#define IT87_REG_TEMP(nr)      (0x29 + (nr))
 
-#define IT87_REG_VIN_MAX(nr)   (0x30 + (nr) * 2)
-#define IT87_REG_VIN_MIN(nr)   (0x31 + (nr) * 2)
+#define IT87_REG_VIN_MAX(nr)   (0x30 + (nr) * 2)
+#define IT87_REG_VIN_MIN(nr)   (0x31 + (nr) * 2)
 
 static const u8 IT87_REG_TEMP_HIGH[] = { 0x40, 0x42, 0x44, 0x46, 0xb4, 0xb6 };
 static const u8 IT87_REG_TEMP_LOW[] =  { 0x41, 0x43, 0x45, 0x47, 0xb5, 0xb7 };
 
-static const u8 IT87_REG_TEMP_HIGH_8686[] =
-                                       0x40, 0x42, 0x44, 0xb4, 0xb6, 0xb8 };
-static const u8 IT87_REG_TEMP_LOW_8686[] =
-                                       0x41, 0x43, 0x45, 0xb5, 0xb7, 0xb9 };
+static const u8 IT87_REG_TEMP_HIGH_8686[] = {
+                                       0x40, 0x42, 0x44, 0xb4, 0xb6, 0xb8 };
+static const u8 IT87_REG_TEMP_LOW_8686[] = {
+                                       0x41, 0x43, 0x45, 0xb5, 0xb7, 0xb9 };
 
-#define IT87_REG_VIN_ENABLE    0x50
-#define IT87_REG_TEMP_ENABLE   0x51
-#define IT87_REG_TEMP_EXTRA    0x55
-#define IT87_REG_BEEP_ENABLE   0x5c
+#define IT87_REG_VIN_ENABLE    0x50
+#define IT87_REG_TEMP_ENABLE   0x51
+#define IT87_REG_TEMP_EXTRA    0x55
+#define IT87_REG_BEEP_ENABLE   0x5c
 
-#define IT87_REG_CHIPID        0x58
+#define IT87_REG_CHIPID                0x58
 
 static const u8 IT87_REG_AUTO_BASE[] = { 0x60, 0x68, 0x70, 0x78, 0xa0, 0xa8 };
 
@@ -335,7 +350,7 @@ static const u16 IT87_REG_TEMP_SRC1[] =     { 0x21d, 0x21e, 0x21f };
 
 struct it87_devices {
        const char *name;
-       const char * const suffix;
+       const char * const model;
        u32 features;
        u8 num_temp_limit;
        u8 num_temp_offset;
@@ -372,11 +387,12 @@ struct it87_devices {
 #define FEAT_11MV_ADC          BIT(24)
 #define FEAT_NEW_TEMPMAP       BIT(25) /* new temp input selection */
 #define FEAT_MMIO              BIT(26) /* Chip supports MMIO */
+#define FEAT_FOUR_TEMP         BIT(27)
 
 static const struct it87_devices it87_devices[] = {
        [it87] = {
                .name = "it87",
-               .suffix = "F",
+               .model = "IT87F",
                .features = FEAT_OLD_AUTOPWM | FEAT_FANCTL_ONOFF,
                                                /* may need to overwrite */
                .num_temp_limit = 3,
@@ -385,7 +401,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8712] = {
                .name = "it8712",
-               .suffix = "F",
+               .model = "IT8712F",
                .features = FEAT_OLD_AUTOPWM | FEAT_VID | FEAT_FANCTL_ONOFF,
                                                /* may need to overwrite */
                .num_temp_limit = 3,
@@ -394,7 +410,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8716] = {
                .name = "it8716",
-               .suffix = "F",
+               .model = "IT8716F",
                .features = FEAT_16BIT_FANS | FEAT_VID
                  | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_PWM_FREQ2
                  | FEAT_FANCTL_ONOFF,
@@ -404,7 +420,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8718] = {
                .name = "it8718",
-               .suffix = "F",
+               .model = "IT8718F",
                .features = FEAT_16BIT_FANS | FEAT_VID
                  | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
                  | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -415,7 +431,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8720] = {
                .name = "it8720",
-               .suffix = "F",
+               .model = "IT8720F",
                .features = FEAT_16BIT_FANS | FEAT_VID
                  | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS
                  | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -426,7 +442,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8721] = {
                .name = "it8721",
-               .suffix = "F",
+               .model = "IT8721F",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
                  | FEAT_FAN16_CONFIG | FEAT_FIVE_FANS | FEAT_IN7_INTERNAL
@@ -439,7 +455,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8728] = {
                .name = "it8728",
-               .suffix = "F",
+               .model = "IT8728F",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_FIVE_FANS
                  | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_SCALING
@@ -451,20 +467,47 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8732] = {
                .name = "it8732",
-               .suffix = "F",
+               .model = "IT8732F",
                .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
                  | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
                  | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
-                 | FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF,
+                 | FEAT_FOUR_PWM | FEAT_FANCTL_ONOFF | FEAT_SCALING,
                .num_temp_limit = 3,
                .num_temp_offset = 3,
                .num_temp_map = 3,
                .peci_mask = 0x07,
                .old_peci_mask = 0x02,  /* Actually reports PCH */
        },
+       [it8736] = {
+               .name = "it8736",
+               .model = "IT8736F",
+               .features = FEAT_16BIT_FANS
+                 | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
+                 | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_FOUR_FANS
+                 | FEAT_FANCTL_ONOFF | FEAT_SCALING,
+               .num_temp_limit = 3,
+               .num_temp_offset = 3,
+               .num_temp_map = 3,
+               .peci_mask = 0x07,
+               .old_peci_mask = 0x02,  /* Actually reports PCH */
+       },
+       [it8738] = {
+               .name = "it8738",
+               .model = "IT8738E",
+               .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
+                 | FEAT_TEMP_OLD_PECI | FEAT_TEMP_PECI
+                 | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL
+                 | FEAT_FANCTL_ONOFF | FEAT_SCALING
+                 | FEAT_AVCC3,
+               .num_temp_limit = 3,
+               .num_temp_offset = 3,
+               .num_temp_map = 3,
+               .peci_mask = 0x07,
+               .old_peci_mask = 0x02,
+       },
        [it8771] = {
                .name = "it8771",
-               .suffix = "E",
+               .model = "IT8771E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
                  | FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
@@ -479,7 +522,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8772] = {
                .name = "it8772",
-               .suffix = "E",
+               .model = "IT8772E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
                  | FEAT_PWM_FREQ2 | FEAT_SCALING | FEAT_FANCTL_ONOFF,
@@ -494,7 +537,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8781] = {
                .name = "it8781",
-               .suffix = "F",
+               .model = "IT8781F",
                .features = FEAT_16BIT_FANS
                  | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
                  | FEAT_FANCTL_ONOFF,
@@ -505,7 +548,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8782] = {
                .name = "it8782",
-               .suffix = "F",
+               .model = "IT8782F",
                .features = FEAT_16BIT_FANS
                  | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
                  | FEAT_FANCTL_ONOFF,
@@ -516,7 +559,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8783] = {
                .name = "it8783",
-               .suffix = "E/F",
+               .model = "IT8783E/F",
                .features = FEAT_16BIT_FANS
                  | FEAT_TEMP_OLD_PECI | FEAT_FAN16_CONFIG | FEAT_PWM_FREQ2
                  | FEAT_FANCTL_ONOFF,
@@ -527,7 +570,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8786] = {
                .name = "it8786",
-               .suffix = "E",
+               .model = "IT8786E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
                  | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -538,7 +581,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8790] = {
                .name = "it8790",
-               .suffix = "E",
+               .model = "IT8790E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
                  | FEAT_16BIT_FANS | FEAT_TEMP_PECI
                  | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -549,7 +592,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8792] = {
                .name = "it8792",
-               .suffix = "E",
+               .model = "IT8792E/IT8795E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_10_9MV_ADC | FEAT_SCALING
                  | FEAT_16BIT_FANS | FEAT_TEMP_PECI
                  | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2 | FEAT_FANCTL_ONOFF,
@@ -560,7 +603,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8603] = {
                .name = "it8603",
-               .suffix = "E",
+               .model = "IT8603E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
                  | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
@@ -569,9 +612,20 @@ static const struct it87_devices it87_devices[] = {
                .num_temp_map = 4,
                .peci_mask = 0x07,
        },
+       [it8606] = {
+               .name = "it8606",
+               .model = "IT8606E",
+               .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
+                 | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL
+                 | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING,
+               .num_temp_limit = 3,
+               .num_temp_offset = 3,
+               .num_temp_map = 3,
+               .peci_mask = 0x07,
+       },
        [it8607] = {
                .name = "it8607",
-               .suffix = "E",
+               .model = "IT8607E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_IN7_INTERNAL | FEAT_NEW_TEMPMAP
                  | FEAT_AVCC3 | FEAT_PWM_FREQ2 | FEAT_SCALING
@@ -583,7 +637,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8613] = {
                .name = "it8613",
-               .suffix = "E",
+               .model = "IT8613E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_11MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_FIVE_FANS
                  | FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
@@ -595,7 +649,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8620] = {
                .name = "it8620",
-               .suffix = "E",
+               .model = "IT8620E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_SIX_FANS
                  | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
@@ -608,19 +662,20 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8622] = {
                .name = "it8622",
-               .suffix = "E",
+               .model = "IT8622E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
-                 | FEAT_TEMP_PECI | FEAT_FIVE_FANS
+                 | FEAT_TEMP_PECI | FEAT_FIVE_FANS | FEAT_FOUR_TEMP
                  | FEAT_FIVE_PWM | FEAT_IN7_INTERNAL | FEAT_PWM_FREQ2
                  | FEAT_AVCC3 | FEAT_VIN3_5V | FEAT_SCALING,
                .num_temp_limit = 3,
                .num_temp_offset = 3,
                .num_temp_map = 4,
-               .peci_mask = 0x07,
+               .peci_mask = 0x0f,
+               .smbus_bitmap = BIT(1) | BIT(2),
        },
        [it8625] = {
                .name = "it8625",
-               .suffix = "E",
+               .model = "IT8625E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
                  | FEAT_AVCC3 | FEAT_NEW_TEMPMAP
                  | FEAT_11MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
@@ -632,7 +687,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8628] = {
                .name = "it8628",
-               .suffix = "E",
+               .model = "IT8628E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_TEMP_PECI | FEAT_SIX_FANS
                  | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
@@ -645,11 +700,11 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8655] = {
                .name = "it8655",
-               .suffix = "E",
+               .model = "IT8655E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
                  | FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
                  | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_BANK_SEL
-                 | FEAT_MMIO,
+                 | FEAT_SIX_TEMP | FEAT_MMIO,
                .num_temp_limit = 6,
                .num_temp_offset = 6,
                .num_temp_map = 6,
@@ -657,11 +712,11 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8665] = {
                .name = "it8665",
-               .suffix = "E",
+               .model = "IT8665E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_16BIT_FANS
                  | FEAT_AVCC3 | FEAT_NEW_TEMPMAP | FEAT_SCALING
                  | FEAT_10_9MV_ADC | FEAT_IN7_INTERNAL | FEAT_SIX_FANS
-                 | FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_MMIO,
+                 | FEAT_SIX_PWM | FEAT_BANK_SEL | FEAT_MMIO | FEAT_SIX_TEMP,
                .num_temp_limit = 6,
                .num_temp_offset = 6,
                .num_temp_map = 6,
@@ -669,7 +724,7 @@ static const struct it87_devices it87_devices[] = {
        },
        [it8686] = {
                .name = "it8686",
-               .suffix = "E",
+               .model = "IT8686E",
                .features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
                  | FEAT_SIX_FANS | FEAT_NEW_TEMPMAP
                  | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
@@ -716,6 +771,7 @@ static const struct it87_devices it87_devices[] = {
 #define has_11mv_adc(data)     ((data)->features & FEAT_11MV_ADC)
 #define has_new_tempmap(data)  ((data)->features & FEAT_NEW_TEMPMAP)
 #define has_mmio(data)         ((data)->features & FEAT_MMIO)
+#define has_four_temp(data)    ((data)->features & FEAT_FOUR_TEMP)
 
 struct it87_sio_data {
        enum chips type;
@@ -748,6 +804,7 @@ struct it87_data {
        u8 old_peci_mask;
 
        u8 smbus_bitmap;        /* !=0 if SMBus needs to be disabled */
+       u8 saved_bank;          /* saved bank register value */
        u8 ec_special_config;   /* EC special config register restore value */
        u8 sioaddr;             /* SIO port address */
        bool doexit;            /* true if exit from sio config is ok */
@@ -768,7 +825,6 @@ struct it87_data {
        const u8 *REG_TEMP_HIGH;
 
        unsigned short addr;
-       const char *name;
        struct mutex update_lock;
        char valid;             /* !=0 if following fields are valid */
        unsigned long last_updated;     /* In jiffies */
@@ -903,7 +959,7 @@ static u8 temp_map_from_reg(const struct it87_data *data, u8 reg)
 {
        u8 map;
 
-       map  = (reg >> data->pwm_temp_map_shift) & data->pwm_temp_map_mask;
+       map = (reg >> data->pwm_temp_map_shift) & data->pwm_temp_map_mask;
        if (map >= data->pwm_num_temp_map)      /* map is 0-based */
                map = 0;
 
@@ -939,6 +995,18 @@ static const unsigned int pwm_freq[8] = {
        750000,
 };
 
+static int _it87_io_read(struct it87_data *data, u16 reg)
+{
+       outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
+       return inb_p(data->addr + IT87_DATA_REG_OFFSET);
+}
+
+static void _it87_io_write(struct it87_data *data, u16 reg, u8 value)
+{
+       outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
+       outb_p(value, data->addr + IT87_DATA_REG_OFFSET);
+}
+
 static int smbus_disable(struct it87_data *data)
 {
        int err;
@@ -951,6 +1019,8 @@ static int smbus_disable(struct it87_data *data)
                superio_outb(data->sioaddr, IT87_SPECIAL_CFG_REG,
                             data->ec_special_config & ~data->smbus_bitmap);
                superio_exit(data->sioaddr, data->doexit);
+               if (has_bank_sel(data) && !data->mmio)
+                       data->saved_bank = _it87_io_read(data, IT87_REG_BANK);
        }
        return 0;
 }
@@ -960,6 +1030,8 @@ static int smbus_enable(struct it87_data *data)
        int err;
 
        if (data->smbus_bitmap) {
+               if (has_bank_sel(data) && !data->mmio)
+                       _it87_io_write(data, IT87_REG_BANK, data->saved_bank);
                err = superio_enter(data->sioaddr);
                if (err)
                        return err;
@@ -972,18 +1044,6 @@ static int smbus_enable(struct it87_data *data)
        return 0;
 }
 
-static int _it87_io_read(struct it87_data *data, u16 reg)
-{
-       outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
-       return inb_p(data->addr + IT87_DATA_REG_OFFSET);
-}
-
-static void _it87_io_write(struct it87_data *data, u16 reg, u8 value)
-{
-       outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
-       outb_p(value, data->addr + IT87_DATA_REG_OFFSET);
-}
-
 static u8 it87_io_set_bank(struct it87_data *data, u8 bank)
 {
        u8 _bank = bank;
@@ -1115,15 +1175,19 @@ static void it87_unlock(struct it87_data *data)
 static struct it87_data *it87_update_device(struct device *dev)
 {
        struct it87_data *data = dev_get_drvdata(dev);
+       struct it87_data *ret = data;
        int err;
        int i;
 
-       err = it87_lock(data);
-       if (err)
-               return ERR_PTR(err);
+       mutex_lock(&data->update_lock);
 
        if (time_after(jiffies, data->last_updated + HZ + HZ / 2) ||
            !data->valid) {
+               err = smbus_disable(data);
+               if (err) {
+                       ret = ERR_PTR(err);
+                       goto unlock;
+               }
                if (update_vbat) {
                        /*
                         * Cleared after each update, so reenable.  Value
@@ -1151,7 +1215,8 @@ static struct it87_data *it87_update_device(struct device *dev)
                        if (!(data->has_fan & BIT(i)))
                                continue;
 
-                       data->fan[i][1] = data->read(data, data->REG_FAN_MIN[i]);
+                       data->fan[i][1] = data->read(data,
+                                                    data->REG_FAN_MIN[i]);
                        data->fan[i][0] = data->read(data, data->REG_FAN[i]);
                        /* Add high byte if in 16-bit mode */
                        if (has_16bit_fans(data)) {
@@ -1219,9 +1284,11 @@ static struct it87_data *it87_update_device(struct device *dev)
                }
                data->last_updated = jiffies;
                data->valid = 1;
+               smbus_enable(data);
        }
-       it87_unlock(data);
-       return data;
+unlock:
+       mutex_unlock(&data->update_lock);
+       return ret;
 }
 
 static ssize_t show_in(struct device *dev, struct device_attribute *attr,
@@ -1263,59 +1330,43 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0);
-static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in,
-                           0, 1);
-static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in,
-                           0, 2);
-
-static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, 0);
-static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in,
-                           1, 1);
-static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in,
-                           1, 2);
-
-static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, 0);
-static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in,
-                           2, 1);
-static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in,
-                           2, 2);
-
-static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, 0);
-static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in,
-                           3, 1);
-static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in,
-                           3, 2);
-
-static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, 0);
-static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in,
-                           4, 1);
-static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in,
-                           4, 2);
-
-static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, 0);
-static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in,
-                           5, 1);
-static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in,
-                           5, 2);
-
-static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 6, 0);
-static SENSOR_DEVICE_ATTR_2(in6_min, S_IRUGO | S_IWUSR, show_in, set_in,
-                           6, 1);
-static SENSOR_DEVICE_ATTR_2(in6_max, S_IRUGO | S_IWUSR, show_in, set_in,
-                           6, 2);
-
-static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 7, 0);
-static SENSOR_DEVICE_ATTR_2(in7_min, S_IRUGO | S_IWUSR, show_in, set_in,
-                           7, 1);
-static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in,
-                           7, 2);
-
-static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0);
-static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 9, 0);
-static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in, NULL, 10, 0);
-static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in, NULL, 11, 0);
-static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in, NULL, 12, 0);
+static SENSOR_DEVICE_ATTR_2(in0_input, 0444, show_in, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(in0_min, 0644, show_in, set_in, 0, 1);
+static SENSOR_DEVICE_ATTR_2(in0_max, 0644, show_in, set_in, 0, 2);
+
+static SENSOR_DEVICE_ATTR_2(in1_input, 0444, show_in, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(in1_min, 0644, show_in, set_in, 1, 1);
+static SENSOR_DEVICE_ATTR_2(in1_max, 0644, show_in, set_in, 1, 2);
+
+static SENSOR_DEVICE_ATTR_2(in2_input, 0444, show_in, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(in2_min, 0644, show_in, set_in, 2, 1);
+static SENSOR_DEVICE_ATTR_2(in2_max, 0644, show_in, set_in, 2, 2);
+
+static SENSOR_DEVICE_ATTR_2(in3_input, 0444, show_in, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(in3_min, 0644, show_in, set_in, 3, 1);
+static SENSOR_DEVICE_ATTR_2(in3_max, 0644, show_in, set_in, 3, 2);
+
+static SENSOR_DEVICE_ATTR_2(in4_input, 0444, show_in, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(in4_min, 0644, show_in, set_in, 4, 1);
+static SENSOR_DEVICE_ATTR_2(in4_max, 0644, show_in, set_in, 4, 2);
+
+static SENSOR_DEVICE_ATTR_2(in5_input, 0444, show_in, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(in5_min, 0644, show_in, set_in, 5, 1);
+static SENSOR_DEVICE_ATTR_2(in5_max, 0644, show_in, set_in, 5, 2);
+
+static SENSOR_DEVICE_ATTR_2(in6_input, 0444, show_in, NULL, 6, 0);
+static SENSOR_DEVICE_ATTR_2(in6_min, 0644, show_in, set_in, 6, 1);
+static SENSOR_DEVICE_ATTR_2(in6_max, 0644, show_in, set_in, 6, 2);
+
+static SENSOR_DEVICE_ATTR_2(in7_input, 0444, show_in, NULL, 7, 0);
+static SENSOR_DEVICE_ATTR_2(in7_min, 0644, show_in, set_in, 7, 1);
+static SENSOR_DEVICE_ATTR_2(in7_max, 0644, show_in, set_in, 7, 2);
+
+static SENSOR_DEVICE_ATTR_2(in8_input, 0444, show_in, NULL, 8, 0);
+static SENSOR_DEVICE_ATTR_2(in9_input, 0444, show_in, NULL, 9, 0);
+static SENSOR_DEVICE_ATTR_2(in10_input, 0444, show_in, NULL, 10, 0);
+static SENSOR_DEVICE_ATTR_2(in11_input, 0444, show_in, NULL, 11, 0);
+static SENSOR_DEVICE_ATTR_2(in12_input, 0444, show_in, NULL, 12, 0);
 
 /* Up to 6 temperatures */
 static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
@@ -1375,48 +1426,30 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
-static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           0, 1);
-static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           0, 2);
-static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp,
-                           set_temp, 0, 3);
-static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0);
-static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           1, 1);
-static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           1, 2);
-static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp,
-                           set_temp, 1, 3);
-static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0);
-static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           2, 1);
-static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           2, 2);
-static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
-                           set_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0);
-static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           3, 1);
-static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           3, 2);
-static SENSOR_DEVICE_ATTR_2(temp4_offset, S_IRUGO | S_IWUSR, show_temp,
-                           set_temp, 3, 3);
-static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0);
-static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           4, 1);
-static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           4, 2);
-static SENSOR_DEVICE_ATTR_2(temp5_offset, S_IRUGO | S_IWUSR, show_temp,
-                           set_temp, 4, 3);
-static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0);
-static SENSOR_DEVICE_ATTR_2(temp6_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           5, 1);
-static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
-                           5, 2);
-static SENSOR_DEVICE_ATTR_2(temp6_offset, S_IRUGO | S_IWUSR, show_temp,
-                           set_temp, 5, 3);
+static SENSOR_DEVICE_ATTR_2(temp1_input, 0444, show_temp, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_min, 0644, show_temp, set_temp, 0, 1);
+static SENSOR_DEVICE_ATTR_2(temp1_max, 0644, show_temp, set_temp, 0, 2);
+static SENSOR_DEVICE_ATTR_2(temp1_offset, 0644, show_temp, set_temp, 0, 3);
+static SENSOR_DEVICE_ATTR_2(temp2_input, 0444, show_temp, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(temp2_min, 0644, show_temp, set_temp, 1, 1);
+static SENSOR_DEVICE_ATTR_2(temp2_max, 0644, show_temp, set_temp, 1, 2);
+static SENSOR_DEVICE_ATTR_2(temp2_offset, 0644, show_temp, set_temp, 1, 3);
+static SENSOR_DEVICE_ATTR_2(temp3_input, 0444, show_temp, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(temp3_min, 0644, show_temp, set_temp, 2, 1);
+static SENSOR_DEVICE_ATTR_2(temp3_max, 0644, show_temp, set_temp, 2, 2);
+static SENSOR_DEVICE_ATTR_2(temp3_offset, 0644, show_temp, set_temp, 2, 3);
+static SENSOR_DEVICE_ATTR_2(temp4_input, 0444, show_temp, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(temp4_min, 0644, show_temp, set_temp, 3, 1);
+static SENSOR_DEVICE_ATTR_2(temp4_max, 0644, show_temp, set_temp, 3, 2);
+static SENSOR_DEVICE_ATTR_2(temp4_offset, 0644, show_temp, set_temp, 3, 3);
+static SENSOR_DEVICE_ATTR_2(temp5_input, 0444, show_temp, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(temp5_min, 0644, show_temp, set_temp, 4, 1);
+static SENSOR_DEVICE_ATTR_2(temp5_max, 0644, show_temp, set_temp, 4, 2);
+static SENSOR_DEVICE_ATTR_2(temp5_offset, 0644, show_temp, set_temp, 4, 3);
+static SENSOR_DEVICE_ATTR_2(temp6_input, 0444, show_temp, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(temp6_min, 0644, show_temp, set_temp, 5, 1);
+static SENSOR_DEVICE_ATTR_2(temp6_max, 0644, show_temp, set_temp, 5, 2);
+static SENSOR_DEVICE_ATTR_2(temp6_offset, 0644, show_temp, set_temp, 5, 3);
 
 static const u8 temp_types_8686[NUM_TEMP][9] = {
        { 0, 8, 8, 8, 8, 8, 8, 8, 7 },
@@ -1430,7 +1463,7 @@ static const u8 temp_types_8686[NUM_TEMP][9] = {
 static int get_temp_type(struct it87_data *data, int index)
 {
        u8 reg, extra;
-       int type = 0;
+       int ttype, type = 0;
 
        if (has_bank_sel(data)) {
                u8 src1, src2;
@@ -1452,7 +1485,7 @@ static int get_temp_type(struct it87_data *data, int index)
                                break;
                        }
                        src2 = data->temp_src[3];
-                       switch(src1) {
+                       switch (src1) {
                        case 3:
                                type = (src2 & BIT(index)) ? 6 : 5;
                                break;
@@ -1470,16 +1503,39 @@ static int get_temp_type(struct it87_data *data, int index)
                        return 0;
                }
        }
-       if (type || index >= 3)
+       if (type)
                return type;
 
+       /* Dectect PECI vs. AMDTSI */
+       ttype = 6;
+       if ((has_temp_peci(data, index)) || data->type == it8721 ||
+           data->type == it8720) {
+               extra = data->read(data, IT87_REG_IFSEL);
+               if ((extra & 0x70) == 0x40)
+                       ttype = 5;
+       }
+
        reg = data->read(data, IT87_REG_TEMP_ENABLE);
+
+       /* Per chip special detection */
+       switch (data->type) {
+       case it8622:
+               if (!(reg & 0xc0) && index == 3)
+                       type = ttype;
+               break;
+       default:
+               break;
+       }
+
+       if (type || index >= 3)
+               return type;
+
        extra = data->read(data, IT87_REG_TEMP_EXTRA);
 
        if ((has_temp_peci(data, index) && (reg >> 6 == index + 1)) ||
            (has_temp_old_peci(data, index) && (extra & 0x80)))
-               type = 6;               /* Intel PECI */
-       if (reg & BIT(index))
+               type = ttype;           /* Intel PECI or AMDTSI */
+       else if (reg & BIT(index))
                type = 3;               /* thermal diode */
        else if (reg & BIT(index + 3))
                type = 4;               /* thermistor */
@@ -1557,18 +1613,12 @@ unlock:
        return count;
 }
 
-static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type,
-                         set_temp_type, 0);
-static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type,
-                         set_temp_type, 1);
-static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
-                         set_temp_type, 2);
-static SENSOR_DEVICE_ATTR(temp4_type, S_IRUGO | S_IWUSR, show_temp_type,
-                         set_temp_type, 3);
-static SENSOR_DEVICE_ATTR(temp5_type, S_IRUGO | S_IWUSR, show_temp_type,
-                         set_temp_type, 4);
-static SENSOR_DEVICE_ATTR(temp6_type, S_IRUGO | S_IWUSR, show_temp_type,
-                         set_temp_type, 5);
+static SENSOR_DEVICE_ATTR(temp1_type, 0644, show_temp_type, set_temp_type, 0);
+static SENSOR_DEVICE_ATTR(temp2_type, 0644, show_temp_type, set_temp_type, 1);
+static SENSOR_DEVICE_ATTR(temp3_type, 0644, show_temp_type, set_temp_type, 2);
+static SENSOR_DEVICE_ATTR(temp4_type, 0644, show_temp_type, set_temp_type, 3);
+static SENSOR_DEVICE_ATTR(temp5_type, 0644, show_temp_type, set_temp_type, 4);
+static SENSOR_DEVICE_ATTR(temp6_type, 0644, show_temp_type, set_temp_type, 5);
 
 /* 6 Fans */
 
@@ -1810,7 +1860,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
 
        err = it87_lock(data);
        if (err)
-               return err;;
+               return err;
 
        it87_update_pwm_ctrl(data, nr);
 
@@ -1932,7 +1982,7 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr,
        val *= has_newer_autopwm(data) ? 256 : 128;
 
        /* Search for the nearest available frequency */
-       for (i = 0; i < 7; i++) {
+       for (i = 0; i < ARRAY_SIZE(pwm_freq) - 1; i++) {
                if (val > (pwm_freq[i] + pwm_freq[i + 1]) / 2)
                        break;
        }
@@ -2141,179 +2191,169 @@ static ssize_t set_auto_temp(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0);
-static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
-                           0, 1);
-static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, show_fan_div,
-                         set_fan_div, 0);
-
-static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, 0);
-static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
-                           1, 1);
-static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, show_fan_div,
-                         set_fan_div, 1);
-
-static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, 0);
-static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
-                           2, 1);
-static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR, show_fan_div,
-                         set_fan_div, 2);
-
-static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, 0);
-static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
-                           3, 1);
-
-static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, 0);
-static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
-                           4, 1);
-
-static SENSOR_DEVICE_ATTR_2(fan6_input, S_IRUGO, show_fan, NULL, 5, 0);
-static SENSOR_DEVICE_ATTR_2(fan6_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
-                           5, 1);
-
-static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(fan1_input, 0444, show_fan, NULL, 0, 0);
+static SENSOR_DEVICE_ATTR_2(fan1_min, 0644, show_fan, set_fan, 0, 1);
+static SENSOR_DEVICE_ATTR(fan1_div, 0644, show_fan_div, set_fan_div, 0);
+
+static SENSOR_DEVICE_ATTR_2(fan2_input, 0444, show_fan, NULL, 1, 0);
+static SENSOR_DEVICE_ATTR_2(fan2_min, 0644, show_fan, set_fan, 1, 1);
+static SENSOR_DEVICE_ATTR(fan2_div, 0644, show_fan_div, set_fan_div, 1);
+
+static SENSOR_DEVICE_ATTR_2(fan3_input, 0444, show_fan, NULL, 2, 0);
+static SENSOR_DEVICE_ATTR_2(fan3_min, 0644, show_fan, set_fan, 2, 1);
+static SENSOR_DEVICE_ATTR(fan3_div, 0644, show_fan_div, set_fan_div, 2);
+
+static SENSOR_DEVICE_ATTR_2(fan4_input, 0444, show_fan, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(fan4_min, 0644, show_fan, set_fan, 3, 1);
+
+static SENSOR_DEVICE_ATTR_2(fan5_input, 0444, show_fan, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(fan5_min, 0644, show_fan, set_fan, 4, 1);
+
+static SENSOR_DEVICE_ATTR_2(fan6_input, 0444, show_fan, NULL, 5, 0);
+static SENSOR_DEVICE_ATTR_2(fan6_min, 0644, show_fan, set_fan, 5, 1);
+
+static SENSOR_DEVICE_ATTR(pwm1_enable, 0644,
                          show_pwm_enable, set_pwm_enable, 0);
-static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
-static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq,
-                         set_pwm_freq, 0);
-static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm1, 0644, show_pwm, set_pwm, 0);
+static SENSOR_DEVICE_ATTR(pwm1_freq, 0644, show_pwm_freq, set_pwm_freq, 0);
+static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, 0444,
                          show_pwm_temp_map, set_pwm_temp_map, 0);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 0, 0);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 0, 1);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 0, 2);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_pwm, 0444,
                            show_auto_pwm, NULL, 0, 3);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, 0644,
                            show_auto_temp, set_auto_temp, 0, 1);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp_hyst, 0644,
                            show_auto_temp, set_auto_temp, 0, 0);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, 0644,
                            show_auto_temp, set_auto_temp, 0, 2);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, 0644,
                            show_auto_temp, set_auto_temp, 0, 3);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, 0644,
                            show_auto_temp, set_auto_temp, 0, 4);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_start, 0644,
                            show_auto_pwm, set_auto_pwm, 0, 0);
-static SENSOR_DEVICE_ATTR(pwm1_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_auto_slope, 0644,
                          show_auto_pwm_slope, set_auto_pwm_slope, 0);
 
-static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm2_enable, 0644,
                          show_pwm_enable, set_pwm_enable, 1);
-static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1);
-static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, set_pwm_freq, 1);
-static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm2, 0644, show_pwm, set_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm2_freq, 0444, show_pwm_freq, set_pwm_freq, 1);
+static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, 0444,
                          show_pwm_temp_map, set_pwm_temp_map, 1);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 1, 0);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 1, 1);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 1, 2);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_pwm, 0444,
                            show_auto_pwm, NULL, 1, 3);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, 0644,
                            show_auto_temp, set_auto_temp, 1, 1);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp_hyst, 0644,
                            show_auto_temp, set_auto_temp, 1, 0);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, 0644,
                            show_auto_temp, set_auto_temp, 1, 2);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, 0644,
                            show_auto_temp, set_auto_temp, 1, 3);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, 0644,
                            show_auto_temp, set_auto_temp, 1, 4);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_start, 0644,
                            show_auto_pwm, set_auto_pwm, 1, 0);
-static SENSOR_DEVICE_ATTR(pwm2_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm2_auto_slope, 0644,
                          show_auto_pwm_slope, set_auto_pwm_slope, 1);
 
-static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm3_enable, 0644,
                          show_pwm_enable, set_pwm_enable, 2);
-static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2);
-static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL, 2);
-static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm3, 0644, show_pwm, set_pwm, 2);
+static SENSOR_DEVICE_ATTR(pwm3_freq, 0444, show_pwm_freq, NULL, 2);
+static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, 0444,
                          show_pwm_temp_map, set_pwm_temp_map, 2);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_pwm, 0644,
                            show_auto_pwm, set_auto_pwm, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_pwm, 0444,
                            show_auto_pwm, NULL, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp_hyst, 0644,
                            show_auto_temp, set_auto_temp, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 4);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_start, 0644,
                            show_auto_pwm, set_auto_pwm, 2, 0);
-static SENSOR_DEVICE_ATTR(pwm3_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm3_auto_slope, 0644,
                          show_auto_pwm_slope, set_auto_pwm_slope, 2);
 
-static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm4_enable, 0644,
                          show_pwm_enable, set_pwm_enable, 3);
-static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 3);
-static SENSOR_DEVICE_ATTR(pwm4_freq, S_IRUGO, show_pwm_freq, NULL, 3);
-static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm4, 0644, show_pwm, set_pwm, 3);
+static SENSOR_DEVICE_ATTR(pwm4_freq, 0444, show_pwm_freq, NULL, 3);
+static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, 0444,
                          show_pwm_temp_map, set_pwm_temp_map, 3);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp_hyst, 0644,
                            show_auto_temp, set_auto_temp, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_point2_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_point3_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm4_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm4_auto_start, 0644,
                            show_auto_pwm, set_auto_pwm, 3, 0);
-static SENSOR_DEVICE_ATTR(pwm4_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm4_auto_slope, 0644,
                          show_auto_pwm_slope, set_auto_pwm_slope, 3);
 
-static SENSOR_DEVICE_ATTR(pwm5_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm5_enable, 0644,
                          show_pwm_enable, set_pwm_enable, 4);
-static SENSOR_DEVICE_ATTR(pwm5, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 4);
-static SENSOR_DEVICE_ATTR(pwm5_freq, S_IRUGO, show_pwm_freq, NULL, 4);
-static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm5, 0644, show_pwm, set_pwm, 4);
+static SENSOR_DEVICE_ATTR(pwm5_freq, 0444, show_pwm_freq, NULL, 4);
+static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, 0444,
                          show_pwm_temp_map, set_pwm_temp_map, 4);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp_hyst, 0644,
                            show_auto_temp, set_auto_temp, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_point2_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_point3_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm5_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm5_auto_start, 0644,
                            show_auto_pwm, set_auto_pwm, 4, 0);
-static SENSOR_DEVICE_ATTR(pwm5_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm5_auto_slope, 0644,
                          show_auto_pwm_slope, set_auto_pwm_slope, 4);
 
-static SENSOR_DEVICE_ATTR(pwm6_enable, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm6_enable, 0644,
                          show_pwm_enable, set_pwm_enable, 5);
-static SENSOR_DEVICE_ATTR(pwm6, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 5);
-static SENSOR_DEVICE_ATTR(pwm6_freq, S_IRUGO, show_pwm_freq, NULL, 5);
-static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO,
+static SENSOR_DEVICE_ATTR(pwm6, 0644, show_pwm, set_pwm, 5);
+static SENSOR_DEVICE_ATTR(pwm6_freq, 0444, show_pwm_freq, NULL, 5);
+static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, 0444,
                          show_pwm_temp_map, set_pwm_temp_map, 5);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 1);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp_hyst, 0644,
                            show_auto_temp, set_auto_temp, 2, 0);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_point2_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_point2_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 2);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_point3_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_point3_temp, 0644,
                            show_auto_temp, set_auto_temp, 2, 3);
-static SENSOR_DEVICE_ATTR_2(pwm6_auto_start, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm6_auto_start, 0644,
                            show_auto_pwm, set_auto_pwm, 5, 0);
-static SENSOR_DEVICE_ATTR(pwm6_auto_slope, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm6_auto_slope, 0644,
                          show_auto_pwm_slope, set_auto_pwm_slope, 5);
 
 /* Alarms */
@@ -2327,7 +2367,7 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
 
        return sprintf(buf, "%u\n", data->alarms);
 }
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+static DEVICE_ATTR(alarms, 0444, show_alarms, NULL);
 
 static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
                          char *buf)
@@ -2365,27 +2405,27 @@ static ssize_t clear_intrusion(struct device *dev,
        return count;
 }
 
-static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 8);
-static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 9);
-static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 10);
-static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 11);
-static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 12);
-static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 13);
-static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 14);
-static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 15);
-static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 0);
-static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 1);
-static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 2);
-static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 3);
-static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 6);
-static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 7);
-static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
-static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
-static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
-static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, 19);
-static SENSOR_DEVICE_ATTR(temp5_alarm, S_IRUGO, show_alarm, NULL, 20);
-static SENSOR_DEVICE_ATTR(temp6_alarm, S_IRUGO, show_alarm, NULL, 21);
-static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(in0_alarm, 0444, show_alarm, NULL, 8);
+static SENSOR_DEVICE_ATTR(in1_alarm, 0444, show_alarm, NULL, 9);
+static SENSOR_DEVICE_ATTR(in2_alarm, 0444, show_alarm, NULL, 10);
+static SENSOR_DEVICE_ATTR(in3_alarm, 0444, show_alarm, NULL, 11);
+static SENSOR_DEVICE_ATTR(in4_alarm, 0444, show_alarm, NULL, 12);
+static SENSOR_DEVICE_ATTR(in5_alarm, 0444, show_alarm, NULL, 13);
+static SENSOR_DEVICE_ATTR(in6_alarm, 0444, show_alarm, NULL, 14);
+static SENSOR_DEVICE_ATTR(in7_alarm, 0444, show_alarm, NULL, 15);
+static SENSOR_DEVICE_ATTR(fan1_alarm, 0444, show_alarm, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_alarm, 0444, show_alarm, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_alarm, 0444, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_alarm, 0444, show_alarm, NULL, 3);
+static SENSOR_DEVICE_ATTR(fan5_alarm, 0444, show_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(fan6_alarm, 0444, show_alarm, NULL, 7);
+static SENSOR_DEVICE_ATTR(temp1_alarm, 0444, show_alarm, NULL, 16);
+static SENSOR_DEVICE_ATTR(temp2_alarm, 0444, show_alarm, NULL, 17);
+static SENSOR_DEVICE_ATTR(temp3_alarm, 0444, show_alarm, NULL, 18);
+static SENSOR_DEVICE_ATTR(temp4_alarm, 0444, show_alarm, NULL, 19);
+static SENSOR_DEVICE_ATTR(temp5_alarm, 0444, show_alarm, NULL, 20);
+static SENSOR_DEVICE_ATTR(temp6_alarm, 0444, show_alarm, NULL, 21);
+static SENSOR_DEVICE_ATTR(intrusion0_alarm, 0644,
                          show_alarm, clear_intrusion, 4);
 
 static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
@@ -2425,29 +2465,29 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(in0_beep, 0644,
                          show_beep, set_beep, 1);
-static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO, show_beep, NULL, 1);
-static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in1_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in3_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in4_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in5_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in6_beep, 0444, show_beep, NULL, 1);
+static SENSOR_DEVICE_ATTR(in7_beep, 0444, show_beep, NULL, 1);
 /* fanX_beep writability is set later */
-static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(fan6_beep, S_IRUGO, show_beep, set_beep, 0);
-static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(fan1_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan2_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan3_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan4_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan5_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(fan6_beep, 0444, show_beep, set_beep, 0);
+static SENSOR_DEVICE_ATTR(temp1_beep, 0644,
                          show_beep, set_beep, 2);
-static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp4_beep, S_IRUGO, show_beep, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp5_beep, S_IRUGO, show_beep, NULL, 2);
-static SENSOR_DEVICE_ATTR(temp6_beep, S_IRUGO, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_beep, 0444, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_beep, 0444, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_beep, 0444, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp5_beep, 0444, show_beep, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp6_beep, 0444, show_beep, NULL, 2);
 
 static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr,
                            char *buf)
@@ -2470,7 +2510,7 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
 
        return count;
 }
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
+static DEVICE_ATTR(vrm, 0644, show_vrm_reg, store_vrm_reg);
 
 static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
                            char *buf)
@@ -2482,7 +2522,7 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
 
        return sprintf(buf, "%ld\n", (long)vid_from_reg(data->vid, data->vrm));
 }
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+static DEVICE_ATTR(cpu0_vid, 0444, show_vid_reg, NULL);
 
 static ssize_t show_label(struct device *dev, struct device_attribute *attr,
                          char *buf)
@@ -2513,11 +2553,11 @@ static ssize_t show_label(struct device *dev, struct device_attribute *attr,
 
        return sprintf(buf, "%s\n", label);
 }
-static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
-static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
-static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
+static SENSOR_DEVICE_ATTR(in3_label, 0444, show_label, NULL, 0);
+static SENSOR_DEVICE_ATTR(in7_label, 0444, show_label, NULL, 1);
+static SENSOR_DEVICE_ATTR(in8_label, 0444, show_label, NULL, 2);
 /* AVCC3 */
-static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 3);
+static SENSOR_DEVICE_ATTR(in9_label, 0444, show_label, NULL, 3);
 
 static umode_t it87_in_is_visible(struct kobject *kobj,
                                  struct attribute *attr, int index)
@@ -2745,7 +2785,7 @@ static umode_t it87_fan_is_visible(struct kobject *kobj,
                        return 0;
                /* first fan beep attribute is writable */
                if (i == __ffs(data->has_fan))
-                       return attr->mode | S_IWUSR;
+                       return attr->mode | 0200;
        }
 
        if (a == 4 && has_16bit_fans(data))     /* divisor */
@@ -2808,11 +2848,11 @@ static umode_t it87_pwm_is_visible(struct kobject *kobj,
 
        /* pwmX_auto_channels_temp is only writable if auto pwm is supported */
        if (a == 3 && (has_old_autopwm(data) || has_newer_autopwm(data)))
-               return attr->mode | S_IWUSR;
+               return attr->mode | 0200;
 
        /* pwm2_freq is writable if there are two pwm frequency selects */
        if (has_pwm_freq2(data) && i == 1 && a == 2)
-               return attr->mode | S_IWUSR;
+               return attr->mode | 0200;
 
        return attr->mode;
 }
@@ -2954,7 +2994,8 @@ static const struct attribute_group it87_group_auto_pwm = {
 
 /* SuperIO detection - will change isa_address if a chip is found */
 static int __init it87_find(int sioaddr, unsigned short *address,
-                           phys_addr_t *mmio_address, struct it87_sio_data *sio_data)
+                           phys_addr_t *mmio_address,
+                           struct it87_sio_data *sio_data)
 {
        const struct it87_devices *config;
        phys_addr_t base = 0;
@@ -3003,6 +3044,12 @@ static int __init it87_find(int sioaddr, unsigned short *address,
        case IT8732F_DEVID:
                sio_data->type = it8732;
                break;
+       case IT8736F_DEVID:
+               sio_data->type = it8736;
+               break;
+       case IT8738E_DEVID:
+               sio_data->type = it8738;
+               break;
        case IT8792E_DEVID:
                sio_data->type = it8792;
                /*
@@ -3039,6 +3086,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
        case IT8623E_DEVID:
                sio_data->type = it8603;
                break;
+       case IT8606E_DEVID:
+               sio_data->type = it8606;
+               break;
        case IT8607E_DEVID:
                sio_data->type = it8607;
                break;
@@ -3107,8 +3157,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
        if (base)
                snprintf(mmio_str, sizeof(mmio_str), " [MMIO at %pa]", &base);
 
-       pr_info("Found IT%04x%s chip at 0x%x%s, revision %d\n", chip_type,
-               it87_devices[sio_data->type].suffix,
+       pr_info("Found %s chip at 0x%x%s, revision %d\n",
+               it87_devices[sio_data->type].model,
                *address, mmio_str, sio_data->revision);
 
        /* in7 (VSB or VCCH5V) is always internal on some chips */
@@ -3207,7 +3257,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
 
                sio_data->beep_pin = superio_inb(sioaddr,
                                                 IT87_SIO_BEEP_PIN_REG) & 0x3f;
-       } else if (sio_data->type == it8603 || sio_data->type == it8607) {
+       } else if (sio_data->type == it8603 || sio_data->type == it8606 ||
+                  sio_data->type == it8607) {
                int reg27, reg29;
 
                superio_select(sioaddr, GPIO);
@@ -3370,7 +3421,8 @@ static int __init it87_find(int sioaddr, unsigned short *address,
 
                sio_data->beep_pin = superio_inb(sioaddr,
                                                 IT87_SIO_BEEP_PIN_REG) & 0x3f;
-       } else if (sio_data->type == it8732) {
+       } else if (sio_data->type == it8732 || sio_data->type == it8736 ||
+                  sio_data->type == it8738) {
                int reg;
 
                superio_select(sioaddr, GPIO);
@@ -3392,9 +3444,11 @@ static int __init it87_find(int sioaddr, unsigned short *address,
                        sio_data->skip_fan |= BIT(3);
 
                /* Check if AVCC is on VIN3 */
-               reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG);
-               if (reg & BIT(0))
-                       sio_data->internal |= BIT(0);
+               if (sio_data->type != it8738) {
+                       reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG);
+                       if (reg & BIT(0))
+                               sio_data->internal |= BIT(0);
+               }
 
                sio_data->beep_pin = superio_inb(sioaddr,
                                                 IT87_SIO_BEEP_PIN_REG) & 0x3f;
@@ -3432,15 +3486,9 @@ static int __init it87_find(int sioaddr, unsigned short *address,
                reg2d = superio_inb(sioaddr, IT87_SIO_PINX4_REG);
                regd3 = superio_inb(sioaddr, IT87_SIO_GPIO9_REG);
 
-               /* Check for pwm2, fan2 */
+               /* Check for pwm2 */
                if (reg29 & BIT(1))
                        sio_data->skip_pwm |= BIT(1);
-               /*
-                * Note: Table 6-1 in datasheet claims that FAN_TAC2
-                * would be enabled with 29h[2]=0.
-                */
-               if (reg2d & BIT(4))
-                       sio_data->skip_fan |= BIT(1);
 
                /* Check for pwm3, fan3 */
                if (reg27 & BIT(6))
@@ -3448,28 +3496,38 @@ static int __init it87_find(int sioaddr, unsigned short *address,
                if (reg27 & BIT(7))
                        sio_data->skip_fan |= BIT(2);
 
-               /* Check for pwm4, fan4, pwm5, fan5 */
+               /* Check for fan2, pwm4, fan4, pwm5, fan5 */
                if (sio_data->type == it8625) {
                        int reg25 = superio_inb(sioaddr, IT87_SIO_GPIO1_REG);
 
+                       if (reg29 & BIT(2))
+                               sio_data->skip_fan |= BIT(1);
                        if (reg25 & BIT(6))
                                sio_data->skip_fan |= BIT(3);
                        if (reg25 & BIT(5))
                                sio_data->skip_pwm |= BIT(3);
                        if (reg27 & BIT(3))
                                sio_data->skip_pwm |= BIT(4);
-                       if (reg27 & BIT(1))
+                       if (!(reg27 & BIT(1)))
                                sio_data->skip_fan |= BIT(4);
                } else {
                        int reg26 = superio_inb(sioaddr, IT87_SIO_GPIO2_REG);
 
+                       if (reg2d & BIT(4))
+                               sio_data->skip_fan |= BIT(1);
                        if (regd3 & BIT(2))
                                sio_data->skip_pwm |= BIT(3);
                        if (regd3 & BIT(3))
                                sio_data->skip_fan |= BIT(3);
                        if (reg26 & BIT(5))
                                sio_data->skip_pwm |= BIT(4);
-                       if (reg26 & BIT(4))
+                       /*
+                        * Table 6-1 in datasheet claims that FAN_TAC5 would
+                        * be enabled with 26h[4]=0. This contradicts with the
+                        * information in section 8.3.9 and with feedback from
+                        * users.
+                        */
+                       if (!(reg26 & BIT(4)))
                                sio_data->skip_fan |= BIT(4);
                }
 
@@ -3885,15 +3943,14 @@ static int it87_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       if (!res)
-               return -EINVAL;
-       if (res->flags & IORESOURCE_IO) {
+       if (res) {
                if (!devm_request_region(dev, res->start, IT87_EC_EXTENT,
                                         DRVNAME)) {
                        dev_err(dev, "Failed to request region %pR\n", res);
                        return -EBUSY;
                }
        } else {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
                data->mmio = devm_ioremap_resource(dev, res);
                if (IS_ERR(data->mmio))
                        return PTR_ERR(data->mmio);
@@ -3942,6 +3999,17 @@ static int it87_probe(struct platform_device *pdev)
        /* Initialize register pointers */
        it87_init_regs(pdev);
 
+       /*
+        * We need to disable SMBus before we can read any registers in
+        * the envmon address space, even if it is for chip identification
+        * purposes. If the chip has SMBus client support, it likely also has
+        * multi-page envmon registers, so we have to set the page anyway
+        * before accessing those registers. Kind of a chicken-and-egg
+        * problem.
+        * Fortunately, the chip was already identified through the SIO
+        * address space, only recent chips are affected, and this is just
+        * an additional safeguard.
+        */
        err = smbus_disable(data);
        if (err)
                return err;
@@ -3984,24 +4052,30 @@ static int it87_probe(struct platform_device *pdev)
        data->in_internal = sio_data->internal;
        data->has_in = 0x3ff & ~sio_data->skip_in;
 
-       if (has_six_temp(data)) {
-               u8 reg = data->read(data, IT87_REG_TEMP456_ENABLE);
-
-               /* Check for additional temperature sensors */
-               if ((reg & 0x03) >= 0x02)
-                       data->has_temp |= BIT(3);
-               if (((reg >> 2) & 0x03) >= 0x02)
-                       data->has_temp |= BIT(4);
-               if (((reg >> 4) & 0x03) >= 0x02)
-                       data->has_temp |= BIT(5);
-
-               /* Check for additional voltage sensors */
-               if ((reg & 0x03) == 0x01)
-                       data->has_in |= BIT(10);
-               if (((reg >> 2) & 0x03) == 0x01)
-                       data->has_in |= BIT(11);
-               if (((reg >> 4) & 0x03) == 0x01)
-                       data->has_in |= BIT(12);
+       if (has_four_temp(data)) {
+               data->has_temp |= BIT(3);
+       } else if (has_six_temp(data)) {
+               if (sio_data->type == it8655 || sio_data->type == it8665) {
+                       data->has_temp |= BIT(3) | BIT(4) | BIT(5);
+               } else {
+                       u8 reg = data->read(data, IT87_REG_TEMP456_ENABLE);
+
+                       /* Check for additional temperature sensors */
+                       if ((reg & 0x03) >= 0x02)
+                               data->has_temp |= BIT(3);
+                       if (((reg >> 2) & 0x03) >= 0x02)
+                               data->has_temp |= BIT(4);
+                       if (((reg >> 4) & 0x03) >= 0x02)
+                               data->has_temp |= BIT(5);
+
+                       /* Check for additional voltage sensors */
+                       if ((reg & 0x03) == 0x01)
+                               data->has_in |= BIT(10);
+                       if (((reg >> 2) & 0x03) == 0x01)
+                               data->has_in |= BIT(11);
+                       if (((reg >> 4) & 0x03) == 0x01)
+                               data->has_in |= BIT(12);
+               }
        }
 
        data->has_beep = !!sio_data->beep_pin;
@@ -4141,21 +4215,24 @@ static struct it87_dmi_data nvidia_fn68pt = {
 static const struct dmi_system_id it87_dmi_table[] __initconst = {
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+                       DMI_MATCH(DMI_SYS_VENDOR,
+                                 "Gigabyte Technology Co., Ltd."),
                        DMI_MATCH(DMI_BOARD_NAME, "AB350"),
                },
                .driver_data = &gigabyte_sio2_force,
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+                       DMI_MATCH(DMI_SYS_VENDOR,
+                                 "Gigabyte Technology Co., Ltd."),
                        DMI_MATCH(DMI_BOARD_NAME, "AX370"),
                },
                .driver_data = &gigabyte_sio2_force,
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+                       DMI_MATCH(DMI_SYS_VENDOR,
+                                 "Gigabyte Technology Co., Ltd."),
                        DMI_MATCH(DMI_BOARD_NAME, "Z97X-Gaming G1"),
                },
                .driver_data = &gigabyte_sio2_force,
@@ -4234,12 +4311,13 @@ static void __exit sm_it87_exit(void)
 
 MODULE_AUTHOR("Chris Gauthron, Jean Delvare <jdelvare@suse.de>");
 MODULE_DESCRIPTION("IT8705F/IT871xF/IT872xF hardware monitoring driver");
-module_param(update_vbat, bool, 0);
+module_param(update_vbat, bool, 0000);
 MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
-module_param(fix_pwm_polarity, bool, 0);
+module_param(fix_pwm_polarity, bool, 0000);
 MODULE_PARM_DESC(fix_pwm_polarity,
                 "Force PWM polarity to active high (DANGEROUS)");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(IT87_DRIVER_VERSION);
 
 module_init(sm_it87_init);
 module_exit(sm_it87_exit);