[ patch .24-rc0 4/5 ] SuperIO locks coordinator - use in drivers/char/pc8736x-gpio
04 - use superio-locks in drivers/char/pc8736x_gpio this driver keeps the slot for the lifetime of the driver ( __init til __exit ), since the driver needs the sio-port to change pin configurations. patches 03,04 were tested on a soekris 4801 a year ago, the box is currently busy. Together they sanity-test the sharing of a reservation with 2 different life-cycles. Signed-off-by: Jim Cromie <[EMAIL PROTECTED]> --- hwmon-superio-pc8736x-gpio Kconfig|1 pc8736x_gpio.c | 83 ++--- 2 files changed, 34 insertions(+), 50 deletions(-) diff -ruNp -X dontdiff -X exclude-diffs hwmon-fan-push-offset/drivers/char/Kconfig hwmon-superio.old/drivers/char/Kconfig --- hwmon-fan-push-offset/drivers/char/Kconfig 2007-10-14 13:00:24.0 -0600 +++ hwmon-superio.old/drivers/char/Kconfig 2007-10-14 17:22:23.0 -0600 @@ -943,6 +943,7 @@ config PC8736x_GPIO depends on X86 default SCx200_GPIO # mostly N select NSC_GPIO # needed for support routines + select SUPERIO_LOCKS help Give userspace access to the GPIO pins on the National Semiconductor PC-8736x (x=[03456]) SuperIO chip. The chip diff -ruNp -X dontdiff -X exclude-diffs hwmon-fan-push-offset/drivers/char/pc8736x_gpio.c hwmon-superio.old/drivers/char/pc8736x_gpio.c --- hwmon-fan-push-offset/drivers/char/pc8736x_gpio.c 2007-10-14 13:00:24.0 -0600 +++ hwmon-superio.old/drivers/char/pc8736x_gpio.c 2007-10-14 17:22:23.0 -0600 @@ -20,6 +20,7 @@ #include #include #include +#include #include #define DEVNAME "pc8736x_gpio" @@ -36,13 +37,12 @@ static DEFINE_MUTEX(pc8736x_gpio_config_ static unsigned pc8736x_gpio_base; static u8 pc8736x_gpio_shadow[4]; -#define SIO_BASE1 0x2E /* 1st command-reg to check */ -#define SIO_BASE2 0x4E /* alt command-reg to check */ +static struct superio* gate; -#define SIO_SID0x20/* SuperI/O ID Register */ -#define SIO_SID_VALUE 0xe9/* Expected value in SuperI/O ID Register */ - -#define SIO_CF10x21/* chip config, bit0 is chip enable */ +static __devinit struct superio_search where = { + .cmdreg_addrs = { 0x2E, 0x4E }, + .device_ids = { 0xE1, 0xE8, 0xE4, 0xE5, 0xE9, 0 }, +}; #define PC8736X_GPIO_RANGE 16 /* ioaddr range */ #define PC8736X_GPIO_CT 32 /* minors matching 4 8 bit ports */ @@ -52,6 +52,7 @@ static u8 pc8736x_gpio_shadow[4]; #define SIO_GPIO_UNIT 0x7 /* unit number of GPIO */ #define SIO_VLM_UNIT0x0D #define SIO_TMS_UNIT0x0E +#define SIO_CF10x21/* chip config, bit0 is chip enable */ /* config-space addrs to read/write each unit's runtime addr */ #define SIO_BASE_HADDR 0x60 @@ -62,7 +63,6 @@ static u8 pc8736x_gpio_shadow[4]; #define SIO_GPIO_PIN_CONFIG 0xF1 #define SIO_GPIO_PIN_EVENT 0xF2 -static unsigned char superio_cmd = 0; static unsigned char selected_device = 0xFF;/* bogus start val */ /* GPIO port runtime access, functionality */ @@ -76,35 +76,9 @@ static int port_offset[] = { 0, 4, 8, 10 static struct platform_device *pdev; /* use in dev_*() */ -static inline void superio_outb(int addr, int val) -{ - outb_p(addr, superio_cmd); - outb_p(val, superio_cmd + 1); -} - -static inline int superio_inb(int addr) -{ - outb_p(addr, superio_cmd); - return inb_p(superio_cmd + 1); -} - -static int pc8736x_superio_present(void) -{ - /* try the 2 possible values, read a hardware reg to verify */ - superio_cmd = SIO_BASE1; - if (superio_inb(SIO_SID) == SIO_SID_VALUE) - return superio_cmd; - - superio_cmd = SIO_BASE2; - if (superio_inb(SIO_SID) == SIO_SID_VALUE) - return superio_cmd; - - return 0; -} - static void device_select(unsigned devldn) { - superio_outb(SIO_UNIT_SEL, devldn); + superio_select(gate, devldn); selected_device = devldn; } @@ -112,7 +86,7 @@ static void select_pin(unsigned iminor) { /* select GPIO port/pin from device minor number */ device_select(SIO_GPIO_UNIT); - superio_outb(SIO_GPIO_PIN_SELECT, + superio_outb(gate, SIO_GPIO_PIN_SELECT, ((iminor << 1) & 0xF0) | (iminor & 0x7)); } @@ -121,19 +95,19 @@ static inline u32 pc8736x_gpio_configure { u32 config, new_config; + superio_enter(gate); mutex_lock(_gpio_config_lock); - device_select(SIO_GPIO_UNIT); + /* read pin's current config value */ select_pin(index); - - /* read current config value */ - config = superio_inb(func_slct); + config = superio_inb(gate, func_slct); /* set new config */ new_config = (config & mask) | bits; - superio_outb(func_slct, new_config); + superio_outb(gate, func_slct, new_config); mutex_unlock(_gpio_config_lock); + superio_exit(gate);
[ patch .24-rc0 4/5 ] SuperIO locks coordinator - use in drivers/char/pc8736x-gpio
04 - use superio-locks in drivers/char/pc8736x_gpio this driver keeps the slot for the lifetime of the driver ( __init til __exit ), since the driver needs the sio-port to change pin configurations. patches 03,04 were tested on a soekris 4801 a year ago, the box is currently busy. Together they sanity-test the sharing of a reservation with 2 different life-cycles. Signed-off-by: Jim Cromie [EMAIL PROTECTED] --- hwmon-superio-pc8736x-gpio Kconfig|1 pc8736x_gpio.c | 83 ++--- 2 files changed, 34 insertions(+), 50 deletions(-) diff -ruNp -X dontdiff -X exclude-diffs hwmon-fan-push-offset/drivers/char/Kconfig hwmon-superio.old/drivers/char/Kconfig --- hwmon-fan-push-offset/drivers/char/Kconfig 2007-10-14 13:00:24.0 -0600 +++ hwmon-superio.old/drivers/char/Kconfig 2007-10-14 17:22:23.0 -0600 @@ -943,6 +943,7 @@ config PC8736x_GPIO depends on X86 default SCx200_GPIO # mostly N select NSC_GPIO # needed for support routines + select SUPERIO_LOCKS help Give userspace access to the GPIO pins on the National Semiconductor PC-8736x (x=[03456]) SuperIO chip. The chip diff -ruNp -X dontdiff -X exclude-diffs hwmon-fan-push-offset/drivers/char/pc8736x_gpio.c hwmon-superio.old/drivers/char/pc8736x_gpio.c --- hwmon-fan-push-offset/drivers/char/pc8736x_gpio.c 2007-10-14 13:00:24.0 -0600 +++ hwmon-superio.old/drivers/char/pc8736x_gpio.c 2007-10-14 17:22:23.0 -0600 @@ -20,6 +20,7 @@ #include linux/mutex.h #include linux/nsc_gpio.h #include linux/platform_device.h +#include linux/superio-locks.h #include asm/uaccess.h #define DEVNAME pc8736x_gpio @@ -36,13 +37,12 @@ static DEFINE_MUTEX(pc8736x_gpio_config_ static unsigned pc8736x_gpio_base; static u8 pc8736x_gpio_shadow[4]; -#define SIO_BASE1 0x2E /* 1st command-reg to check */ -#define SIO_BASE2 0x4E /* alt command-reg to check */ +static struct superio* gate; -#define SIO_SID0x20/* SuperI/O ID Register */ -#define SIO_SID_VALUE 0xe9/* Expected value in SuperI/O ID Register */ - -#define SIO_CF10x21/* chip config, bit0 is chip enable */ +static __devinit struct superio_search where = { + .cmdreg_addrs = { 0x2E, 0x4E }, + .device_ids = { 0xE1, 0xE8, 0xE4, 0xE5, 0xE9, 0 }, +}; #define PC8736X_GPIO_RANGE 16 /* ioaddr range */ #define PC8736X_GPIO_CT 32 /* minors matching 4 8 bit ports */ @@ -52,6 +52,7 @@ static u8 pc8736x_gpio_shadow[4]; #define SIO_GPIO_UNIT 0x7 /* unit number of GPIO */ #define SIO_VLM_UNIT0x0D #define SIO_TMS_UNIT0x0E +#define SIO_CF10x21/* chip config, bit0 is chip enable */ /* config-space addrs to read/write each unit's runtime addr */ #define SIO_BASE_HADDR 0x60 @@ -62,7 +63,6 @@ static u8 pc8736x_gpio_shadow[4]; #define SIO_GPIO_PIN_CONFIG 0xF1 #define SIO_GPIO_PIN_EVENT 0xF2 -static unsigned char superio_cmd = 0; static unsigned char selected_device = 0xFF;/* bogus start val */ /* GPIO port runtime access, functionality */ @@ -76,35 +76,9 @@ static int port_offset[] = { 0, 4, 8, 10 static struct platform_device *pdev; /* use in dev_*() */ -static inline void superio_outb(int addr, int val) -{ - outb_p(addr, superio_cmd); - outb_p(val, superio_cmd + 1); -} - -static inline int superio_inb(int addr) -{ - outb_p(addr, superio_cmd); - return inb_p(superio_cmd + 1); -} - -static int pc8736x_superio_present(void) -{ - /* try the 2 possible values, read a hardware reg to verify */ - superio_cmd = SIO_BASE1; - if (superio_inb(SIO_SID) == SIO_SID_VALUE) - return superio_cmd; - - superio_cmd = SIO_BASE2; - if (superio_inb(SIO_SID) == SIO_SID_VALUE) - return superio_cmd; - - return 0; -} - static void device_select(unsigned devldn) { - superio_outb(SIO_UNIT_SEL, devldn); + superio_select(gate, devldn); selected_device = devldn; } @@ -112,7 +86,7 @@ static void select_pin(unsigned iminor) { /* select GPIO port/pin from device minor number */ device_select(SIO_GPIO_UNIT); - superio_outb(SIO_GPIO_PIN_SELECT, + superio_outb(gate, SIO_GPIO_PIN_SELECT, ((iminor 1) 0xF0) | (iminor 0x7)); } @@ -121,19 +95,19 @@ static inline u32 pc8736x_gpio_configure { u32 config, new_config; + superio_enter(gate); mutex_lock(pc8736x_gpio_config_lock); - device_select(SIO_GPIO_UNIT); + /* read pin's current config value */ select_pin(index); - - /* read current config value */ - config = superio_inb(func_slct); + config = superio_inb(gate, func_slct); /* set new config */ new_config = (config mask) | bits; - superio_outb(func_slct, new_config); + superio_outb(gate, func_slct, new_config);