diff options
author | Jean Delvare <khali@linux-fr.org> | 2009-06-15 12:39:50 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-06-15 12:39:50 -0400 |
commit | 2958b1ec6be1d71105d67d70de9d7d70f5e97151 (patch) | |
tree | cf4c9b80aea488135435bef72de68b940efe7849 | |
parent | c1e48dce05ff06266cdfd0cba55fc5367cd499a5 (diff) |
hwmon: PCI quirk for hwmon access on MSI MS-7031 board
The MSI MS-7031 is based on an ATI IXP300 south bridge. On this south
bridge, accessible I/O ports must be enabled explicitly. Unfortunately
the BIOS forgets to enable access to the hardware monitoring chip I/O
ports, so hardware monitoring fails.
Add a quirk enabling access to the required ports (0x295-0x296). This
is exactly what MSI's own hardware monitoring application is doing, so
it has to be the right way.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r-- | drivers/hwmon/hwmon.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index e15c3e7b07e9..29ea6753f3bb 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/hwmon.h> | 18 | #include <linux/hwmon.h> |
19 | #include <linux/gfp.h> | 19 | #include <linux/gfp.h> |
20 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
21 | #include <linux/pci.h> | ||
21 | 22 | ||
22 | #define HWMON_ID_PREFIX "hwmon" | 23 | #define HWMON_ID_PREFIX "hwmon" |
23 | #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" | 24 | #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" |
@@ -86,8 +87,36 @@ void hwmon_device_unregister(struct device *dev) | |||
86 | "hwmon_device_unregister() failed: bad class ID!\n"); | 87 | "hwmon_device_unregister() failed: bad class ID!\n"); |
87 | } | 88 | } |
88 | 89 | ||
90 | static void __init hwmon_pci_quirks(void) | ||
91 | { | ||
92 | #if defined CONFIG_X86 && defined CONFIG_PCI | ||
93 | struct pci_dev *sb; | ||
94 | u16 base; | ||
95 | u8 enable; | ||
96 | |||
97 | /* Open access to 0x295-0x296 on MSI MS-7031 */ | ||
98 | sb = pci_get_device(PCI_VENDOR_ID_ATI, 0x436c, NULL); | ||
99 | if (sb && | ||
100 | (sb->subsystem_vendor == 0x1462 && /* MSI */ | ||
101 | sb->subsystem_device == 0x0031)) { /* MS-7031 */ | ||
102 | |||
103 | pci_read_config_byte(sb, 0x48, &enable); | ||
104 | pci_read_config_word(sb, 0x64, &base); | ||
105 | |||
106 | if (base == 0 && !(enable & BIT(2))) { | ||
107 | dev_info(&sb->dev, | ||
108 | "Opening wide generic port at 0x295\n"); | ||
109 | pci_write_config_word(sb, 0x64, 0x295); | ||
110 | pci_write_config_byte(sb, 0x48, enable | BIT(2)); | ||
111 | } | ||
112 | } | ||
113 | #endif | ||
114 | } | ||
115 | |||
89 | static int __init hwmon_init(void) | 116 | static int __init hwmon_init(void) |
90 | { | 117 | { |
118 | hwmon_pci_quirks(); | ||
119 | |||
91 | hwmon_class = class_create(THIS_MODULE, "hwmon"); | 120 | hwmon_class = class_create(THIS_MODULE, "hwmon"); |
92 | if (IS_ERR(hwmon_class)) { | 121 | if (IS_ERR(hwmon_class)) { |
93 | printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n"); | 122 | printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n"); |