aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/hwmon.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-06-15 12:39:50 -0400
committerJean Delvare <khali@linux-fr.org>2009-06-15 12:39:50 -0400
commit2958b1ec6be1d71105d67d70de9d7d70f5e97151 (patch)
treecf4c9b80aea488135435bef72de68b940efe7849 /drivers/hwmon/hwmon.c
parentc1e48dce05ff06266cdfd0cba55fc5367cd499a5 (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>
Diffstat (limited to 'drivers/hwmon/hwmon.c')
-rw-r--r--drivers/hwmon/hwmon.c29
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
90static 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
89static int __init hwmon_init(void) 116static 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");