aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2015-02-06 21:53:21 -0500
committerGuenter Roeck <linux@roeck-us.net>2015-03-15 11:54:12 -0400
commitd2a14ea51a4d7e506b2ebac2c57a32ad577ed693 (patch)
treeb22d1e2c344cc7b0da549dbed18a504951aaadfc
parent48e9318256da995681e6420732055e34f93bddc1 (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.c35
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
890struct nct6775_sio_data { 891struct 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)
4006static int __maybe_unused nct6775_resume(struct device *dev) 4008static 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++) {