02 - use superio-locks in drivers/hwmon/w83627hf.c tested on an AMD-Barton mobo. Signed-off-by: Jim Cromie <jim.cromie at gmail.com> --- hwmon-superio-w83627hf Kconfig | 1 w83627hf.c | 140 ++++++++++++++++++++++++------------------------------------- 2 files changed, 58 insertions(+), 83 deletions(-) diff -ruNp -X dontdiff -X exclude-diffs hwmon-fan-push-offset/drivers/hwmon/Kconfig hwmon-superio.old/drivers/hwmon/Kconfig --- hwmon-fan-push-offset/drivers/hwmon/Kconfig 2007-10-14 13:00:24.000000000 -0600 +++ hwmon-superio.old/drivers/hwmon/Kconfig 2007-10-14 17:22:23.000000000 -0600 @@ -675,6 +688,7 @@ config SENSORS_W83L785TS config SENSORS_W83627HF tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF" select HWMON_VID + select SUPERIO_LOCKS help If you say yes here you get support for the Winbond W836X7 series of sensor chips: the W83627HF, W83627THF, W83637HF, W83687THF and diff -ruNp -X dontdiff -X exclude-diffs hwmon-fan-push-offset/drivers/hwmon/w83627hf.c hwmon-superio.old/drivers/hwmon/w83627hf.c --- hwmon-fan-push-offset/drivers/hwmon/w83627hf.c 2007-10-14 17:13:47.000000000 -0600 +++ hwmon-superio.old/drivers/hwmon/w83627hf.c 2007-10-14 17:22:23.000000000 -0600 @@ -50,6 +50,7 @@ #include <linux/err.h> #include <linux/mutex.h> #include <linux/ioport.h> +#include <linux/superio-locks.h> #include <asm/io.h> #include "lm75.h" @@ -75,11 +76,6 @@ static int init = 1; module_param(init, bool, 0); MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); -/* modified from kernel/include/traps.c */ -static int REG; /* The register to read/write */ -#define DEV 0x07 /* Register: Logical device select */ -static int VAL; /* The value to read/write */ - /* logical device numbers for superio_select (below) */ #define W83627HF_LD_FDC 0x00 #define W83627HF_LD_PRT 0x01 @@ -97,8 +93,6 @@ static int VAL; /* The value to read/wr #define W83627HF_LD_ACPI 0x0a #define W83627HF_LD_HWM 0x0b -#define DEVID 0x20 /* Register: Device ID */ - #define W83627THF_GPIO5_EN 0x30 /* w83627thf only */ #define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ #define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */ @@ -107,47 +101,25 @@ static int VAL; /* The value to read/wr #define W83687THF_VID_CFG 0xF0 /* w83687thf only */ #define W83687THF_VID_DATA 0xF1 /* w83687thf only */ -static inline void -superio_outb(int reg, int val) -{ - outb(reg, REG); - outb(val, VAL); -} - -static inline int -superio_inb(int reg) -{ - outb(reg, REG); - return inb(VAL); -} - -static inline void -superio_select(int ld) -{ - outb(DEV, REG); - outb(ld, VAL); -} - -static inline void -superio_enter(void) -{ - outb(0x87, REG); - outb(0x87, REG); -} - -static inline void -superio_exit(void) -{ - outb(0xAA, REG); -} +#define W627_DEVID 0x52 +#define W627THF_DEVID 0x82 +#define W697_DEVID 0x60 +#define W637_DEVID 0x70 +#define W687THF_DEVID 0x85 + +#define WINB_ACT_REG 0x30 +#define WINB_BASE_REG 0x60 + +static struct superio* gate; + +static __devinit struct superio_search where = { + .cmdreg_addrs = { 0x2e, 0x4e }, + .device_ids = { W627_DEVID, W627THF_DEVID, W697_DEVID, + W637_DEVID, W687THF_DEVID, 0 }, + .enter_seq = { 0x87, 0x87, 0 }, + .exit_seq = { 0xAA, 0 } +}; -#define W627_DEVID 0x52 -#define W627THF_DEVID 0x82 -#define W697_DEVID 0x60 -#define W637_DEVID 0x70 -#define W687THF_DEVID 0x85 -#define WINB_ACT_REG 0x30 -#define WINB_BASE_REG 0x60 /* Constants specified below */ /* Alignment of the base address */ @@ -995,12 +967,10 @@ show_name(struct device *dev, struct dev return sprintf(buf, "%s\n", data->name); } static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - -static int __init w83627hf_find(int sioaddr, unsigned short *addr, - struct w83627hf_sio_data *sio_data) + +static u16 __init w83627hf_find(struct w83627hf_sio_data *sio_data) { - int err = -ENODEV; - u16 val; + u16 val, addr = 0; static const __initdata char *names[] = { "W83627HF", @@ -1010,11 +980,15 @@ static int __init w83627hf_find(int sioa "W83687THF", }; - REG = sioaddr; - VAL = sioaddr + 1; + gate = superio_find(&where); + if (!gate) { + printk(KERN_WARNING DRVNAME ": superio port not detected, " + "module not intalled.\n"); + return 0; + } + superio_enter(gate); + val = superio_devid(gate); - superio_enter(); - val= superio_inb(DEVID); switch (val) { case W627_DEVID: sio_data->type = w83627hf; @@ -1038,36 +1012,34 @@ static int __init w83627hf_find(int sioa goto exit; } - superio_select(W83627HF_LD_HWM); + superio_select(gate, W83627HF_LD_HWM); force_addr &= WINB_ALIGNMENT; if (force_addr) { printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n", force_addr); - superio_outb(WINB_BASE_REG, force_addr >> 8); - superio_outb(WINB_BASE_REG + 1, force_addr & 0xff); + superio_outb(gate, WINB_BASE_REG, force_addr >> 8); + superio_outb(gate, WINB_BASE_REG + 1, force_addr & 0xff); } - val = (superio_inb(WINB_BASE_REG) << 8) | - superio_inb(WINB_BASE_REG + 1); - *addr = val & WINB_ALIGNMENT; - if (*addr == 0) { + val = superio_inw(gate, WINB_BASE_REG); + addr = val & WINB_ALIGNMENT; + if (addr == 0) { printk(KERN_WARNING DRVNAME ": Base address not set, " "skipping\n"); goto exit; } - val = superio_inb(WINB_ACT_REG); + val = superio_inb(gate, WINB_ACT_REG); if (!(val & 0x01)) { printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n"); - superio_outb(WINB_ACT_REG, val | 0x01); + superio_outb(gate, WINB_ACT_REG, val | 0x01); } - err = 0; pr_info(DRVNAME ": Found %s chip at %#x\n", - names[sio_data->type], *addr); + names[sio_data->type], addr); exit: - superio_exit(); - return err; + superio_exit(gate); + return addr; } #define VIN_UNIT_ATTRS(_X_) \ @@ -1337,18 +1309,18 @@ static int __devinit w83627thf_read_gpio { int res = 0xff, sel; - superio_enter(); - superio_select(W83627HF_LD_GPIO5); + superio_enter(gate); + superio_select(gate, W83627HF_LD_GPIO5); /* Make sure these GPIO pins are enabled */ - if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) { + if (!(superio_inb(gate, W83627THF_GPIO5_EN) & (1<<3))) { dev_dbg(&pdev->dev, "GPIO5 disabled, no VID function\n"); goto exit; } /* Make sure the pins are configured for input There must be at least five (VRM 9), and possibly 6 (VRM 10) */ - sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f; + sel = superio_inb(gate, W83627THF_GPIO5_IOSR) & 0x3f; if ((sel & 0x1f) != 0x1f) { dev_dbg(&pdev->dev, "GPIO5 not configured for VID " "function\n"); @@ -1356,10 +1328,10 @@ static int __devinit w83627thf_read_gpio } dev_info(&pdev->dev, "Reading VID from GPIO5\n"); - res = superio_inb(W83627THF_GPIO5_DR) & sel; + res = superio_inb(gate, W83627THF_GPIO5_DR) & sel; exit: - superio_exit(); + superio_exit(gate); return res; } @@ -1367,26 +1339,26 @@ static int __devinit w83687thf_read_vid( { int res = 0xff; - superio_enter(); - superio_select(W83627HF_LD_HWM); + superio_enter(gate); + superio_select(gate, W83627HF_LD_HWM); /* Make sure these GPIO pins are enabled */ - if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) { + if (!(superio_inb(gate, W83687THF_VID_EN) & (1 << 2))) { dev_dbg(&pdev->dev, "VID disabled, no VID function\n"); goto exit; } /* Make sure the pins are configured for input */ - if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) { + if (!(superio_inb(gate, W83687THF_VID_CFG) & (1 << 4))) { dev_dbg(&pdev->dev, "VID configured as output, " "no VID function\n"); goto exit; } - res = superio_inb(W83687THF_VID_DATA) & 0x3f; + res = superio_inb(gate, W83687THF_VID_DATA) & 0x3f; exit: - superio_exit(); + superio_exit(gate); return res; } @@ -1669,8 +1641,8 @@ static int __init sensors_w83627hf_init( unsigned short address; struct w83627hf_sio_data sio_data; - if (w83627hf_find(0x2e, &address, &sio_data) - && w83627hf_find(0x4e, &address, &sio_data)) + address = w83627hf_find(&sio_data); + if (!address) return -ENODEV; err = platform_driver_register(&w83627hf_driver); @@ -1692,6 +1664,8 @@ exit: static void __exit sensors_w83627hf_exit(void) { + if (gate) + superio_release(gate); platform_device_unregister(pdev); platform_driver_unregister(&w83627hf_driver); }