aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-12-06 17:13:42 -0500
committerMark M. Hoffman <mhoffman@lightlink.com>2008-02-07 20:39:42 -0500
commit67b671bceb4a8340a30929e9642620d99ed5ad76 (patch)
treed302333633bdbd752151933366aaaabfdc60e719
parentb20ff13a6ad64f07ce78c75e6a335c185270d73c (diff)
hwmon: Let the user override the detected Super-I/O device ID
While it is possible to force SMBus-based hardware monitoring chip drivers to drive a not officially supported device, we do not have this possibility for Super-I/O-based drivers. That's unfortunate because sometimes newer chips are fully compatible and just forcing the driver to load would work. Instead of that we have to tell the users to recompile the kernel driver, which isn't an easy task for everyone. So, I propose that we add a module parameter to all Super-I/O based hardware monitoring drivers, letting advanced users force the driver to load on their machine. The user has to provide the device ID of a supposedly compatible device. This requires looking at the source code or a datasheet, so I am confident that users can't randomly force a driver without knowing what they are doing. Thus this should be relatively safe. As you can see from the code, the implementation is pretty simple and unintrusive. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Hans de Goede <j.w.r.degoede@hhs.nl> Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
-rw-r--r--drivers/hwmon/dme1737.c6
-rw-r--r--drivers/hwmon/f71805f.c6
-rw-r--r--drivers/hwmon/f71882fg.c6
-rw-r--r--drivers/hwmon/it87.c6
-rw-r--r--drivers/hwmon/pc87360.c6
-rw-r--r--drivers/hwmon/pc87427.c6
-rw-r--r--drivers/hwmon/smsc47b397.c6
-rw-r--r--drivers/hwmon/smsc47m1.c6
-rw-r--r--drivers/hwmon/vt1211.c8
-rw-r--r--drivers/hwmon/w83627ehf.c11
-rw-r--r--drivers/hwmon/w83627hf.c6
11 files changed, 61 insertions, 12 deletions
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index a878c98e252e..85064fb0b7c2 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -44,6 +44,10 @@ static int force_start;
44module_param(force_start, bool, 0); 44module_param(force_start, bool, 0);
45MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs"); 45MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs");
46 46
47static unsigned short force_id;
48module_param(force_id, ushort, 0);
49MODULE_PARM_DESC(force_id, "Override the detected device ID");
50
47/* Addresses to scan */ 51/* Addresses to scan */
48static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; 52static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
49 53
@@ -2191,7 +2195,7 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr)
2191 /* Check device ID 2195 /* Check device ID
2192 * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and 2196 * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and
2193 * SCH3116 (0x7f). */ 2197 * SCH3116 (0x7f). */
2194 reg = dme1737_sio_inb(sio_cip, 0x20); 2198 reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
2195 if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { 2199 if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) {
2196 err = -ENODEV; 2200 err = -ENODEV;
2197 goto exit; 2201 goto exit;
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 5d9d5cc816a2..7a14a2dbb752 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -41,6 +41,10 @@
41#include <linux/ioport.h> 41#include <linux/ioport.h>
42#include <asm/io.h> 42#include <asm/io.h>
43 43
44static unsigned short force_id;
45module_param(force_id, ushort, 0);
46MODULE_PARM_DESC(force_id, "Override the detected device ID");
47
44static struct platform_device *pdev; 48static struct platform_device *pdev;
45 49
46#define DRVNAME "f71805f" 50#define DRVNAME "f71805f"
@@ -1497,7 +1501,7 @@ static int __init f71805f_find(int sioaddr, unsigned short *address,
1497 if (devid != SIO_FINTEK_ID) 1501 if (devid != SIO_FINTEK_ID)
1498 goto exit; 1502 goto exit;
1499 1503
1500 devid = superio_inw(sioaddr, SIO_REG_DEVID); 1504 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
1501 switch (devid) { 1505 switch (devid) {
1502 case SIO_F71805F_ID: 1506 case SIO_F71805F_ID:
1503 sio_data->kind = f71805f; 1507 sio_data->kind = f71805f;
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 6db74434a02e..cbeb4984b5c7 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -74,6 +74,10 @@
74 74
75#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ 75#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
76 76
77static unsigned short force_id;
78module_param(force_id, ushort, 0);
79MODULE_PARM_DESC(force_id, "Override the detected device ID");
80
77static struct platform_device *f71882fg_pdev = NULL; 81static struct platform_device *f71882fg_pdev = NULL;
78 82
79/* Super-I/O Function prototypes */ 83/* Super-I/O Function prototypes */
@@ -843,7 +847,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address)
843 goto exit; 847 goto exit;
844 } 848 }
845 849
846 devid = superio_inw(sioaddr, SIO_REG_DEVID); 850 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
847 if (devid != SIO_F71882_ID) { 851 if (devid != SIO_F71882_ID) {
848 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n"); 852 printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
849 goto exit; 853 goto exit;
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index ad6c8a319903..0932fd53352a 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -52,6 +52,10 @@
52 52
53enum chips { it87, it8712, it8716, it8718 }; 53enum chips { it87, it8712, it8716, it8718 };
54 54
55static unsigned short force_id;
56module_param(force_id, ushort, 0);
57MODULE_PARM_DESC(force_id, "Override the detected device ID");
58
55static struct platform_device *pdev; 59static struct platform_device *pdev;
56 60
57#define REG 0x2e /* The register to read/write */ 61#define REG 0x2e /* The register to read/write */
@@ -906,7 +910,7 @@ static int __init it87_find(unsigned short *address,
906 u16 chip_type; 910 u16 chip_type;
907 911
908 superio_enter(); 912 superio_enter();
909 chip_type = superio_inw(DEVID); 913 chip_type = force_id ? force_id : superio_inw(DEVID);
910 914
911 switch (chip_type) { 915 switch (chip_type) {
912 case IT8705F_DEVID: 916 case IT8705F_DEVID:
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 9d660133d517..9b462bb13fa3 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -59,6 +59,10 @@ MODULE_PARM_DESC(init,
59 " 2: Forcibly enable all voltage and temperature channels, except in9\n" 59 " 2: Forcibly enable all voltage and temperature channels, except in9\n"
60 " 3: Forcibly enable all voltage and temperature channels, including in9"); 60 " 3: Forcibly enable all voltage and temperature channels, including in9");
61 61
62static unsigned short force_id;
63module_param(force_id, ushort, 0);
64MODULE_PARM_DESC(force_id, "Override the detected device ID");
65
62/* 66/*
63 * Super-I/O registers and operations 67 * Super-I/O registers and operations
64 */ 68 */
@@ -826,7 +830,7 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
826 /* No superio_enter */ 830 /* No superio_enter */
827 831
828 /* Identify device */ 832 /* Identify device */
829 val = superio_inb(sioaddr, DEVID); 833 val = force_id ? force_id : superio_inb(sioaddr, DEVID);
830 switch (val) { 834 switch (val) {
831 case 0xE1: /* PC87360 */ 835 case 0xE1: /* PC87360 */
832 case 0xE8: /* PC87363 */ 836 case 0xE8: /* PC87363 */
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index d40509ad6ae6..7265f22ae5cd 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -34,6 +34,10 @@
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <asm/io.h> 35#include <asm/io.h>
36 36
37static unsigned short force_id;
38module_param(force_id, ushort, 0);
39MODULE_PARM_DESC(force_id, "Override the detected device ID");
40
37static struct platform_device *pdev; 41static struct platform_device *pdev;
38 42
39#define DRVNAME "pc87427" 43#define DRVNAME "pc87427"
@@ -555,7 +559,7 @@ static int __init pc87427_find(int sioaddr, unsigned short *address)
555 int i, err = 0; 559 int i, err = 0;
556 560
557 /* Identify device */ 561 /* Identify device */
558 val = superio_inb(sioaddr, SIOREG_DEVID); 562 val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
559 if (val != 0xf2) { /* PC87427 */ 563 if (val != 0xf2) { /* PC87427 */
560 err = -ENODEV; 564 err = -ENODEV;
561 goto exit; 565 goto exit;
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 0b57d2ea2cf7..f61d8f4185b2 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -38,6 +38,10 @@
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39#include <asm/io.h> 39#include <asm/io.h>
40 40
41static unsigned short force_id;
42module_param(force_id, ushort, 0);
43MODULE_PARM_DESC(force_id, "Override the detected device ID");
44
41static struct platform_device *pdev; 45static struct platform_device *pdev;
42 46
43#define DRVNAME "smsc47b397" 47#define DRVNAME "smsc47b397"
@@ -333,7 +337,7 @@ static int __init smsc47b397_find(unsigned short *addr)
333 u8 id, rev; 337 u8 id, rev;
334 338
335 superio_enter(); 339 superio_enter();
336 id = superio_inb(SUPERIO_REG_DEVID); 340 id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
337 341
338 if ((id != 0x6f) && (id != 0x81) && (id != 0x85)) { 342 if ((id != 0x6f) && (id != 0x81) && (id != 0x85)) {
339 superio_exit(); 343 superio_exit();
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index a10a380868e2..0d7f0c4d06bb 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -39,6 +39,10 @@
39#include <linux/sysfs.h> 39#include <linux/sysfs.h>
40#include <asm/io.h> 40#include <asm/io.h>
41 41
42static unsigned short force_id;
43module_param(force_id, ushort, 0);
44MODULE_PARM_DESC(force_id, "Override the detected device ID");
45
42static struct platform_device *pdev; 46static struct platform_device *pdev;
43 47
44#define DRVNAME "smsc47m1" 48#define DRVNAME "smsc47m1"
@@ -399,7 +403,7 @@ static int __init smsc47m1_find(unsigned short *addr,
399 u8 val; 403 u8 val;
400 404
401 superio_enter(); 405 superio_enter();
402 val = superio_inb(SUPERIO_REG_DEVID); 406 val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
403 407
404 /* 408 /*
405 * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x 409 * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 7dfcc8dd316d..12b43590fa53 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -42,6 +42,10 @@ static int int_mode = -1;
42module_param(int_mode, int, 0); 42module_param(int_mode, int, 0);
43MODULE_PARM_DESC(int_mode, "Force the temperature interrupt mode"); 43MODULE_PARM_DESC(int_mode, "Force the temperature interrupt mode");
44 44
45static unsigned short force_id;
46module_param(force_id, ushort, 0);
47MODULE_PARM_DESC(force_id, "Override the detected device ID");
48
45static struct platform_device *pdev; 49static struct platform_device *pdev;
46 50
47#define DRVNAME "vt1211" 51#define DRVNAME "vt1211"
@@ -1280,10 +1284,12 @@ EXIT:
1280static int __init vt1211_find(int sio_cip, unsigned short *address) 1284static int __init vt1211_find(int sio_cip, unsigned short *address)
1281{ 1285{
1282 int err = -ENODEV; 1286 int err = -ENODEV;
1287 int devid;
1283 1288
1284 superio_enter(sio_cip); 1289 superio_enter(sio_cip);
1285 1290
1286 if (superio_inb(sio_cip, SIO_VT1211_DEVID) != SIO_VT1211_ID) { 1291 devid = force_id ? force_id : superio_inb(sio_cip, SIO_VT1211_DEVID);
1292 if (devid != SIO_VT1211_ID) {
1287 goto EXIT; 1293 goto EXIT;
1288 } 1294 }
1289 1295
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index d5aa25ce5dbd..699592855bd8 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -59,6 +59,10 @@ static const char * w83627ehf_device_names[] = {
59 "w83627dhg", 59 "w83627dhg",
60}; 60};
61 61
62static unsigned short force_id;
63module_param(force_id, ushort, 0);
64MODULE_PARM_DESC(force_id, "Override the detected device ID");
65
62#define DRVNAME "w83627ehf" 66#define DRVNAME "w83627ehf"
63 67
64/* 68/*
@@ -1445,8 +1449,11 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
1445 1449
1446 superio_enter(sioaddr); 1450 superio_enter(sioaddr);
1447 1451
1448 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) 1452 if (force_id)
1449 | superio_inb(sioaddr, SIO_REG_DEVID + 1); 1453 val = force_id;
1454 else
1455 val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
1456 | superio_inb(sioaddr, SIO_REG_DEVID + 1);
1450 switch (val & SIO_ID_MASK) { 1457 switch (val & SIO_ID_MASK) {
1451 case SIO_W83627EHF_ID: 1458 case SIO_W83627EHF_ID:
1452 sio_data->kind = w83627ehf; 1459 sio_data->kind = w83627ehf;
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 879d0a6544cc..181f4e8590b1 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -75,6 +75,10 @@ static int init = 1;
75module_param(init, bool, 0); 75module_param(init, bool, 0);
76MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); 76MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
77 77
78static unsigned short force_id;
79module_param(force_id, ushort, 0);
80MODULE_PARM_DESC(force_id, "Override the detected device ID");
81
78/* modified from kernel/include/traps.c */ 82/* modified from kernel/include/traps.c */
79static int REG; /* The register to read/write */ 83static int REG; /* The register to read/write */
80#define DEV 0x07 /* Register: Logical device select */ 84#define DEV 0x07 /* Register: Logical device select */
@@ -1014,7 +1018,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr,
1014 VAL = sioaddr + 1; 1018 VAL = sioaddr + 1;
1015 1019
1016 superio_enter(); 1020 superio_enter();
1017 val= superio_inb(DEVID); 1021 val = force_id ? force_id : superio_inb(DEVID);
1018 switch (val) { 1022 switch (val) {
1019 case W627_DEVID: 1023 case W627_DEVID:
1020 sio_data->type = w83627hf; 1024 sio_data->type = w83627hf;