diff options
author | Guenter Roeck <linux@roeck-us.net> | 2013-12-25 10:25:59 -0500 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2014-01-15 00:36:53 -0500 |
commit | f5776cc3b55b9b2412df5008bfd7a98075a4891d (patch) | |
tree | 734a35dac22fe309ebacb68094ea85f565ad1a02 | |
parent | 2ac1dfc52dc862eabf30d5ece51f3422e6df561a (diff) |
hwmon: (nct6775) Re-enable logical device mapping for NCT6791 during resume
After a suspend/resume cycle, the NCT6791 is back to its original BIOS
programming. In this state, HWMON IO access may be locked.
Re-enable it during resume.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/nct6775.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index cf811c1a1475..8686e966fa28 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c | |||
@@ -3936,6 +3936,18 @@ static int nct6775_probe(struct platform_device *pdev) | |||
3936 | return PTR_ERR_OR_ZERO(hwmon_dev); | 3936 | return PTR_ERR_OR_ZERO(hwmon_dev); |
3937 | } | 3937 | } |
3938 | 3938 | ||
3939 | static void nct6791_enable_io_mapping(int sioaddr) | ||
3940 | { | ||
3941 | int val; | ||
3942 | |||
3943 | val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE); | ||
3944 | if (val & 0x10) { | ||
3945 | pr_info("Enabling hardware monitor logical device mappings.\n"); | ||
3946 | superio_outb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE, | ||
3947 | val & ~0x10); | ||
3948 | } | ||
3949 | } | ||
3950 | |||
3939 | #ifdef CONFIG_PM | 3951 | #ifdef CONFIG_PM |
3940 | static int nct6775_suspend(struct device *dev) | 3952 | static int nct6775_suspend(struct device *dev) |
3941 | { | 3953 | { |
@@ -3955,11 +3967,20 @@ static int nct6775_suspend(struct device *dev) | |||
3955 | static int nct6775_resume(struct device *dev) | 3967 | static int nct6775_resume(struct device *dev) |
3956 | { | 3968 | { |
3957 | struct nct6775_data *data = dev_get_drvdata(dev); | 3969 | struct nct6775_data *data = dev_get_drvdata(dev); |
3958 | int i, j; | 3970 | int i, j, err = 0; |
3959 | 3971 | ||
3960 | mutex_lock(&data->update_lock); | 3972 | mutex_lock(&data->update_lock); |
3961 | data->bank = 0xff; /* Force initial bank selection */ | 3973 | data->bank = 0xff; /* Force initial bank selection */ |
3962 | 3974 | ||
3975 | if (data->kind == nct6791) { | ||
3976 | err = superio_enter(data->sioreg); | ||
3977 | if (err) | ||
3978 | goto abort; | ||
3979 | |||
3980 | nct6791_enable_io_mapping(data->sioreg); | ||
3981 | superio_exit(data->sioreg); | ||
3982 | } | ||
3983 | |||
3963 | /* Restore limits */ | 3984 | /* Restore limits */ |
3964 | for (i = 0; i < data->in_num; i++) { | 3985 | for (i = 0; i < data->in_num; i++) { |
3965 | if (!(data->have_in & (1 << i))) | 3986 | if (!(data->have_in & (1 << i))) |
@@ -3996,11 +4017,12 @@ static int nct6775_resume(struct device *dev) | |||
3996 | nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2); | 4017 | nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2); |
3997 | } | 4018 | } |
3998 | 4019 | ||
4020 | abort: | ||
3999 | /* Force re-reading all values */ | 4021 | /* Force re-reading all values */ |
4000 | data->valid = false; | 4022 | data->valid = false; |
4001 | mutex_unlock(&data->update_lock); | 4023 | mutex_unlock(&data->update_lock); |
4002 | 4024 | ||
4003 | return 0; | 4025 | return err; |
4004 | } | 4026 | } |
4005 | 4027 | ||
4006 | static const struct dev_pm_ops nct6775_dev_pm_ops = { | 4028 | static const struct dev_pm_ops nct6775_dev_pm_ops = { |
@@ -4088,15 +4110,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data) | |||
4088 | pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); | 4110 | pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); |
4089 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); | 4111 | superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); |
4090 | } | 4112 | } |
4091 | if (sio_data->kind == nct6791) { | 4113 | |
4092 | val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE); | 4114 | if (sio_data->kind == nct6791) |
4093 | if (val & 0x10) { | 4115 | nct6791_enable_io_mapping(sioaddr); |
4094 | pr_info("Enabling hardware monitor logical device mappings.\n"); | ||
4095 | superio_outb(sioaddr, | ||
4096 | NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE, | ||
4097 | val & ~0x10); | ||
4098 | } | ||
4099 | } | ||
4100 | 4116 | ||
4101 | superio_exit(sioaddr); | 4117 | superio_exit(sioaddr); |
4102 | pr_info("Found %s or compatible chip at %#x:%#x\n", | 4118 | pr_info("Found %s or compatible chip at %#x:%#x\n", |