diff options
author | Guenter Roeck <linux@roeck-us.net> | 2015-02-06 21:53:21 -0500 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2015-03-15 11:54:12 -0400 |
commit | d2a14ea51a4d7e506b2ebac2c57a32ad577ed693 (patch) | |
tree | b22d1e2c344cc7b0da549dbed18a504951aaadfc | |
parent | 48e9318256da995681e6420732055e34f93bddc1 (diff) |
hwmon: (nct6775) Restore hardware monitoring logical device status on resume
After a suspend/resume cycle it is not guaranteed that the hardware monitoring
device is still enabled. Ensure that this is the case after resume.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/nct6775.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index db6a68efc389..0445a52379e7 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -885,6 +885,7 @@ struct nct6775_data { | |||
885 | u8 vbat; | 885 | u8 vbat; |
886 | u8 fandiv1; | 886 | u8 fandiv1; |
887 | u8 fandiv2; | 887 | u8 fandiv2; |
888 | u8 sio_reg_enable; | ||
888 | }; | 889 | }; |
889 | 890 | ||
890 | struct nct6775_sio_data { | 891 | struct nct6775_sio_data { |
@@ -3177,6 +3178,10 @@ nct6775_check_fan_inputs(struct nct6775_data *data) | |||
3177 | int sioreg = data->sioreg; | 3178 | int sioreg = data->sioreg; |
3178 | int regval; | 3179 | int regval; |
3179 | 3180 | ||
3181 | /* Store SIO_REG_ENABLE for use during resume */ | ||
3182 | superio_select(sioreg, NCT6775_LD_HWM); | ||
3183 | data->sio_reg_enable = superio_inb(sioreg, SIO_REG_ENABLE); | ||
3184 | |||
3180 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ | 3185 | /* fan4 and fan5 share some pins with the GPIO and serial flash */ |
3181 | if (data->kind == nct6775) { | 3186 | if (data->kind == nct6775) { |
3182 | regval = superio_inb(sioreg, 0x2c); | 3187 | regval = superio_inb(sioreg, 0x2c); |
@@ -3195,20 +3200,17 @@ nct6775_check_fan_inputs(struct nct6775_data *data) | |||
3195 | } else if (data->kind == nct6776) { | 3200 | } else if (data->kind == nct6776) { |
3196 | bool gpok = superio_inb(sioreg, 0x27) & 0x80; | 3201 | bool gpok = superio_inb(sioreg, 0x27) & 0x80; |
3197 | 3202 | ||
3198 | superio_select(sioreg, NCT6775_LD_HWM); | 3203 | if (data->sio_reg_enable & 0x80) |
3199 | regval = superio_inb(sioreg, SIO_REG_ENABLE); | ||
3200 | |||
3201 | if (regval & 0x80) | ||
3202 | fan3pin = gpok; | 3204 | fan3pin = gpok; |
3203 | else | 3205 | else |
3204 | fan3pin = !(superio_inb(sioreg, 0x24) & 0x40); | 3206 | fan3pin = !(superio_inb(sioreg, 0x24) & 0x40); |
3205 | 3207 | ||
3206 | if (regval & 0x40) | 3208 | if (data->sio_reg_enable & 0x40) |
3207 | fan4pin = gpok; | 3209 | fan4pin = gpok; |
3208 | else | 3210 | else |
3209 | fan4pin = superio_inb(sioreg, 0x1C) & 0x01; | 3211 | fan4pin = superio_inb(sioreg, 0x1C) & 0x01; |
3210 | 3212 | ||
3211 | if (regval & 0x20) | 3213 | if (data->sio_reg_enable & 0x20) |
3212 | fan5pin = gpok; | 3214 | fan5pin = gpok; |
3213 | else | 3215 | else |
3214 | fan5pin = superio_inb(sioreg, 0x1C) & 0x02; | 3216 | fan5pin = superio_inb(sioreg, 0x1C) & 0x02; |
@@ -4006,19 +4008,26 @@ static int __maybe_unused nct6775_suspend(struct device *dev) | |||
4006 | static int __maybe_unused nct6775_resume(struct device *dev) | 4008 | static int __maybe_unused nct6775_resume(struct device *dev) |
4007 | { | 4009 | { |
4008 | struct nct6775_data *data = dev_get_drvdata(dev); | 4010 | struct nct6775_data *data = dev_get_drvdata(dev); |
4011 | int sioreg = data->sioreg; | ||
4009 | int i, j, err = 0; | 4012 | int i, j, err = 0; |
4013 | u8 reg; | ||
4010 | 4014 | ||
4011 | mutex_lock(&data->update_lock); | 4015 | mutex_lock(&data->update_lock); |
4012 | data->bank = 0xff; /* Force initial bank selection */ | 4016 | data->bank = 0xff; /* Force initial bank selection */ |
4013 | 4017 | ||
4014 | if (data->kind == nct6791 || data->kind == nct6792) { | 4018 | err = superio_enter(sioreg); |
4015 | err = superio_enter(data->sioreg); | 4019 | if (err) |
4016 | if (err) | 4020 | goto abort; |
4017 | goto abort; | ||
4018 | 4021 | ||
4019 | nct6791_enable_io_mapping(data->sioreg); | 4022 | superio_select(sioreg, NCT6775_LD_HWM); |
4020 | superio_exit(data->sioreg); | 4023 | reg = superio_inb(sioreg, SIO_REG_ENABLE); |
4021 | } | 4024 | if (reg != data->sio_reg_enable) |
4025 | superio_outb(sioreg, SIO_REG_ENABLE, data->sio_reg_enable); | ||
4026 | |||
4027 | if (data->kind == nct6791 || data->kind == nct6792) | ||
4028 | nct6791_enable_io_mapping(sioreg); | ||
4029 | |||
4030 | superio_exit(sioreg); | ||
4022 | 4031 | ||
4023 | /* Restore limits */ | 4032 | /* Restore limits */ |
4024 | for (i = 0; i < data->in_num; i++) { | 4033 | for (i = 0; i < data->in_num; i++) { |