[PATCH] hwmon: Let the user overrule the detected Super-I/O device ID

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jean Delvare wrote:
> 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 at linux-fr.org>


Sounds like a good plan to me and the patch looks good to me too, notice that 
it touches lots of files, so despite a best effort I may have overlooked a typo 
of some kind.

Acked-by: Hans de Goede <j.w.r.degoede at hhs.nl>

Regards,

Hans



> ---
>  drivers/hwmon/dme1737.c    |    6 +++++-
>  drivers/hwmon/f71805f.c    |    6 +++++-
>  drivers/hwmon/f71882fg.c   |    6 +++++-
>  drivers/hwmon/it87.c       |    6 +++++-
>  drivers/hwmon/pc87360.c    |    6 +++++-
>  drivers/hwmon/pc87427.c    |    6 +++++-
>  drivers/hwmon/smsc47b397.c |    6 +++++-
>  drivers/hwmon/smsc47m1.c   |    6 +++++-
>  drivers/hwmon/vt1211.c     |    8 +++++++-
>  drivers/hwmon/w83627ehf.c  |   11 +++++++++--
>  drivers/hwmon/w83627hf.c   |    6 +++++-
>  11 files changed, 61 insertions(+), 12 deletions(-)
> 
> --- linux-2.6.24-rc2.orig/drivers/hwmon/f71805f.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/f71805f.c	2007-11-08 23:23:38.000000000 +0100
> @@ -42,6 +42,10 @@
>  #include <linux/acpi.h>
>  #include <asm/io.h>
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  static struct platform_device *pdev;
>  
>  #define DRVNAME "f71805f"
> @@ -1502,7 +1506,7 @@ static int __init f71805f_find(int sioad
>  	if (devid != SIO_FINTEK_ID)
>  		goto exit;
>  
> -	devid = superio_inw(sioaddr, SIO_REG_DEVID);
> +	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
>  	switch (devid) {
>  	case SIO_F71805F_ID:
>  		sio_data->kind = f71805f;
> --- linux-2.6.24-rc2.orig/drivers/hwmon/f71882fg.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/f71882fg.c	2007-11-08 23:36:51.000000000 +0100
> @@ -75,6 +75,10 @@
>  
>  #define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  static struct platform_device *f71882fg_pdev = NULL;
>  
>  /* Super-I/O Function prototypes */
> @@ -844,7 +848,7 @@ static int __init f71882fg_find(int sioa
>  		goto exit;
>  	}
>  
> -	devid = superio_inw(sioaddr, SIO_REG_DEVID);
> +	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
>  	if (devid != SIO_F71882_ID) {
>  		printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
>  		goto exit;
> --- linux-2.6.24-rc2.orig/drivers/hwmon/pc87360.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/pc87360.c	2007-11-08 23:38:59.000000000 +0100
> @@ -60,6 +60,10 @@ MODULE_PARM_DESC(init,
>   " 2: Forcibly enable all voltage and temperature channels, except in9\n"
>   " 3: Forcibly enable all voltage and temperature channels, including in9");
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  /*
>   * Super-I/O registers and operations
>   */
> @@ -827,7 +831,7 @@ static int __init pc87360_find(int sioad
>  	/* No superio_enter */
>  
>  	/* Identify device */
> -	val = superio_inb(sioaddr, DEVID);
> +	val = force_id ? force_id : superio_inb(sioaddr, DEVID);
>  	switch (val) {
>  	case 0xE1: /* PC87360 */
>  	case 0xE8: /* PC87363 */
> --- linux-2.6.24-rc2.orig/drivers/hwmon/pc87427.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/pc87427.c	2007-11-08 23:38:50.000000000 +0100
> @@ -35,6 +35,10 @@
>  #include <linux/acpi.h>
>  #include <asm/io.h>
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  static struct platform_device *pdev;
>  
>  #define DRVNAME "pc87427"
> @@ -560,7 +564,7 @@ static int __init pc87427_find(int sioad
>  	int i, err = 0;
>  
>  	/* Identify device */
> -	val = superio_inb(sioaddr, SIOREG_DEVID);
> +	val = force_id ? force_id : superio_inb(sioaddr, SIOREG_DEVID);
>  	if (val != 0xf2) {	/* PC87427 */
>  		err = -ENODEV;
>  		goto exit;
> --- linux-2.6.24-rc2.orig/drivers/hwmon/dme1737.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/dme1737.c	2007-11-08 23:43:19.000000000 +0100
> @@ -45,6 +45,10 @@ static int force_start;
>  module_param(force_start, bool, 0);
>  MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs");
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  /* Addresses to scan */
>  static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
>  
> @@ -2192,7 +2196,7 @@ static int __init dme1737_isa_detect(int
>  	/* Check device ID
>  	 * We currently know about SCH3112 (0x7c), SCH3114 (0x7d), and
>  	 * SCH3116 (0x7f). */
> -	reg = dme1737_sio_inb(sio_cip, 0x20);
> +	reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
>  	if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) {
>  		err = -ENODEV;
>  		goto exit;
> --- linux-2.6.24-rc2.orig/drivers/hwmon/it87.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/it87.c	2007-11-08 23:43:34.000000000 +0100
> @@ -45,6 +45,10 @@
>  
>  enum chips { it87, it8712, it8716, it8718 };
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  static struct platform_device *pdev;
>  
>  #define	REG	0x2e	/* The register to read/write */
> @@ -893,7 +897,7 @@ static int __init it87_find(unsigned sho
>  	u16 chip_type;
>  
>  	superio_enter();
> -	chip_type = superio_inw(DEVID);
> +	chip_type = force_id ? force_id : superio_inw(DEVID);
>  
>  	switch (chip_type) {
>  	case IT8705F_DEVID:
> --- linux-2.6.24-rc2.orig/drivers/hwmon/smsc47b397.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/smsc47b397.c	2007-11-08 23:43:48.000000000 +0100
> @@ -39,6 +39,10 @@
>  #include <linux/acpi.h>
>  #include <asm/io.h>
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  static struct platform_device *pdev;
>  
>  #define DRVNAME "smsc47b397"
> @@ -338,7 +342,7 @@ static int __init smsc47b397_find(unsign
>  	u8 id, rev;
>  
>  	superio_enter();
> -	id = superio_inb(SUPERIO_REG_DEVID);
> +	id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
>  
>  	if ((id != 0x6f) && (id != 0x81) && (id != 0x85)) {
>  		superio_exit();
> --- linux-2.6.24-rc2.orig/drivers/hwmon/smsc47m1.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/smsc47m1.c	2007-11-08 23:44:10.000000000 +0100
> @@ -40,6 +40,10 @@
>  #include <linux/acpi.h>
>  #include <asm/io.h>
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  static struct platform_device *pdev;
>  
>  #define DRVNAME "smsc47m1"
> @@ -400,7 +404,7 @@ static int __init smsc47m1_find(unsigned
>  	u8 val;
>  
>  	superio_enter();
> -	val = superio_inb(SUPERIO_REG_DEVID);
> +	val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
>  
>  	/*
>  	 * SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x
> --- linux-2.6.24-rc2.orig/drivers/hwmon/vt1211.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/vt1211.c	2007-11-08 23:45:05.000000000 +0100
> @@ -43,6 +43,10 @@ static int int_mode = -1;
>  module_param(int_mode, int, 0);
>  MODULE_PARM_DESC(int_mode, "Force the temperature interrupt mode");
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  static struct platform_device *pdev;
>  
>  #define DRVNAME "vt1211"
> @@ -1285,10 +1289,12 @@ EXIT:
>  static int __init vt1211_find(int sio_cip, unsigned short *address)
>  {
>  	int err = -ENODEV;
> +	int devid;
>  
>  	superio_enter(sio_cip);
>  
> -	if (superio_inb(sio_cip, SIO_VT1211_DEVID) != SIO_VT1211_ID) {
> +	devid = force_id ? force_id : superio_inb(sio_cip, SIO_VT1211_DEVID);
> +	if (devid != SIO_VT1211_ID) {
>  		goto EXIT;
>  	}
>  
> --- linux-2.6.24-rc2.orig/drivers/hwmon/w83627ehf.c	2007-11-07 20:18:20.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/w83627ehf.c	2007-11-08 23:45:56.000000000 +0100
> @@ -60,6 +60,10 @@ static const char * w83627ehf_device_nam
>  	"w83627dhg",
>  };
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  #define DRVNAME "w83627ehf"
>  
>  /*
> @@ -1438,8 +1442,11 @@ static int __init w83627ehf_find(int sio
>  
>  	superio_enter(sioaddr);
>  
> -	val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
> -	    | superio_inb(sioaddr, SIO_REG_DEVID + 1);
> +	if (force_id)
> +		val = force_id;
> +	else
> +		val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8)
> +		    | superio_inb(sioaddr, SIO_REG_DEVID + 1);
>  	switch (val & SIO_ID_MASK) {
>  	case SIO_W83627EHF_ID:
>  		sio_data->kind = w83627ehf;
> --- linux-2.6.24-rc2.orig/drivers/hwmon/w83627hf.c	2007-11-08 22:59:44.000000000 +0100
> +++ linux-2.6.24-rc2/drivers/hwmon/w83627hf.c	2007-11-08 23:46:11.000000000 +0100
> @@ -76,6 +76,10 @@ static int init = 1;
>  module_param(init, bool, 0);
>  MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
>  
> +static unsigned short force_id;
> +module_param(force_id, ushort, 0);
> +MODULE_PARM_DESC(force_id, "Overrule the detected device ID");
> +
>  /* modified from kernel/include/traps.c */
>  static int REG;		/* The register to read/write */
>  #define	DEV	0x07	/* Register: Logical device select */
> @@ -1015,7 +1019,7 @@ static int __init w83627hf_find(int sioa
>  	VAL = sioaddr + 1;
>  
>  	superio_enter();
> -	val= superio_inb(DEVID);
> +	val = force_id ? force_id : superio_inb(DEVID);
>  	switch (val) {
>  	case W627_DEVID:
>  		sio_data->type = w83627hf;
> 
> 






[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux