diff options
author | Jean Delvare <khali@linux-fr.org> | 2007-12-06 17:13:42 -0500 |
---|---|---|
committer | Mark M. Hoffman <mhoffman@lightlink.com> | 2008-02-07 20:39:42 -0500 |
commit | 67b671bceb4a8340a30929e9642620d99ed5ad76 (patch) | |
tree | d302333633bdbd752151933366aaaabfdc60e719 | |
parent | b20ff13a6ad64f07ce78c75e6a335c185270d73c (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.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/f71805f.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/f71882fg.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/pc87360.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/pc87427.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/smsc47b397.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/smsc47m1.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/vt1211.c | 8 | ||||
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 11 | ||||
-rw-r--r-- | drivers/hwmon/w83627hf.c | 6 |
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; | |||
44 | module_param(force_start, bool, 0); | 44 | module_param(force_start, bool, 0); |
45 | MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs"); | 45 | MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs"); |
46 | 46 | ||
47 | static unsigned short force_id; | ||
48 | module_param(force_id, ushort, 0); | ||
49 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
50 | |||
47 | /* Addresses to scan */ | 51 | /* Addresses to scan */ |
48 | static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END}; | 52 | static 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 | ||
44 | static unsigned short force_id; | ||
45 | module_param(force_id, ushort, 0); | ||
46 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
47 | |||
44 | static struct platform_device *pdev; | 48 | static 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 | ||
77 | static unsigned short force_id; | ||
78 | module_param(force_id, ushort, 0); | ||
79 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
80 | |||
77 | static struct platform_device *f71882fg_pdev = NULL; | 81 | static 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 | ||
53 | enum chips { it87, it8712, it8716, it8718 }; | 53 | enum chips { it87, it8712, it8716, it8718 }; |
54 | 54 | ||
55 | static unsigned short force_id; | ||
56 | module_param(force_id, ushort, 0); | ||
57 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
58 | |||
55 | static struct platform_device *pdev; | 59 | static 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 | ||
62 | static unsigned short force_id; | ||
63 | module_param(force_id, ushort, 0); | ||
64 | MODULE_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 | ||
37 | static unsigned short force_id; | ||
38 | module_param(force_id, ushort, 0); | ||
39 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
40 | |||
37 | static struct platform_device *pdev; | 41 | static 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 | ||
41 | static unsigned short force_id; | ||
42 | module_param(force_id, ushort, 0); | ||
43 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
44 | |||
41 | static struct platform_device *pdev; | 45 | static 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 | ||
42 | static unsigned short force_id; | ||
43 | module_param(force_id, ushort, 0); | ||
44 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
45 | |||
42 | static struct platform_device *pdev; | 46 | static 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; | |||
42 | module_param(int_mode, int, 0); | 42 | module_param(int_mode, int, 0); |
43 | MODULE_PARM_DESC(int_mode, "Force the temperature interrupt mode"); | 43 | MODULE_PARM_DESC(int_mode, "Force the temperature interrupt mode"); |
44 | 44 | ||
45 | static unsigned short force_id; | ||
46 | module_param(force_id, ushort, 0); | ||
47 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
48 | |||
45 | static struct platform_device *pdev; | 49 | static struct platform_device *pdev; |
46 | 50 | ||
47 | #define DRVNAME "vt1211" | 51 | #define DRVNAME "vt1211" |
@@ -1280,10 +1284,12 @@ EXIT: | |||
1280 | static int __init vt1211_find(int sio_cip, unsigned short *address) | 1284 | static 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 | ||
62 | static unsigned short force_id; | ||
63 | module_param(force_id, ushort, 0); | ||
64 | MODULE_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; | |||
75 | module_param(init, bool, 0); | 75 | module_param(init, bool, 0); |
76 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); | 76 | MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); |
77 | 77 | ||
78 | static unsigned short force_id; | ||
79 | module_param(force_id, ushort, 0); | ||
80 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | ||
81 | |||
78 | /* modified from kernel/include/traps.c */ | 82 | /* modified from kernel/include/traps.c */ |
79 | static int REG; /* The register to read/write */ | 83 | static 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; |