From: Jim Cromie <jim.cromie@gmail.com>
To: Linux kernel <linux-kernel@vger.kernel.org>,
LM Sensors <lm-sensors@lm-sensors.org>
Subject: [lm-sensors] [ patch .24-rc0 4/5 ] SuperIO locks coordinator - use
Date: Mon, 15 Oct 2007 05:08:31 +0000 [thread overview]
Message-ID: <4712F5CF.3030807@gmail.com> (raw)
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 <jim.cromie@gmail.com>
---
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.000000000 -0600
+++ hwmon-superio.old/drivers/char/Kconfig 2007-10-14 17:22:23.000000000 -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.000000000 -0600
+++ hwmon-superio.old/drivers/char/pc8736x_gpio.c 2007-10-14 17:22:23.000000000 -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_SID 0x20 /* SuperI/O ID Register */
-#define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */
-
-#define SIO_CF1 0x21 /* 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_UNIT 0x0D
#define SIO_TMS_UNIT 0x0E
+#define SIO_CF1 0x21 /* 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);
mutex_unlock(&pc8736x_gpio_config_lock);
+ superio_exit(gate);
return config;
}
@@ -259,40 +233,44 @@ static int __init pc8736x_gpio_init(void
rc = -ENODEV;
goto undo_platform_dev_alloc;
}
+ pc8736x_gpio_ops.dev = &pdev->dev;
+
dev_info(&pdev->dev, "NatSemi pc8736x GPIO Driver Initializing\n");
- if (!pc8736x_superio_present()) {
+ gate = superio_find(&where);
+ if (!gate) {
rc = -ENODEV;
- dev_err(&pdev->dev, "no device found\n");
+ dev_err(&pdev->dev, "no superio port found\n");
+ // goto err2;
goto undo_platform_dev_add;
}
- pc8736x_gpio_ops.dev = &pdev->dev;
/* Verify that chip and it's GPIO unit are both enabled.
My BIOS does this, so I take minimum action here
*/
- rc = superio_inb(SIO_CF1);
+ superio_enter(gate);
+ rc = superio_inb(gate, SIO_CF1);
if (!(rc & 0x01)) {
rc = -ENODEV;
dev_err(&pdev->dev, "device not enabled\n");
- goto undo_platform_dev_add;
+ goto undo_superio_enter;
}
device_select(SIO_GPIO_UNIT);
- if (!superio_inb(SIO_UNIT_ACT)) {
+ if (!superio_inb(gate, SIO_UNIT_ACT)) {
rc = -ENODEV;
dev_err(&pdev->dev, "GPIO unit not enabled\n");
- goto undo_platform_dev_add;
+ goto undo_superio_enter;
}
/* read the GPIO unit base addr that chip responds to */
- pc8736x_gpio_base = (superio_inb(SIO_BASE_HADDR) << 8
- | superio_inb(SIO_BASE_LADDR));
+ pc8736x_gpio_base = (superio_inb(gate, SIO_BASE_HADDR) << 8
+ | superio_inb(gate, SIO_BASE_LADDR));
if (!request_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE, DEVNAME)) {
rc = -ENODEV;
dev_err(&pdev->dev, "GPIO ioport %x busy\n",
pc8736x_gpio_base);
- goto undo_platform_dev_add;
+ goto undo_superio_enter;
}
dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base);
@@ -319,10 +297,14 @@ static int __init pc8736x_gpio_init(void
cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fileops);
cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT);
+ superio_exit(gate); /* no release, we need to stay registered */
return 0;
undo_request_region:
release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE);
+undo_superio_enter:
+ superio_exit(gate);
+ superio_release(gate);
undo_platform_dev_add:
platform_device_del(pdev);
undo_platform_dev_alloc:
@@ -341,6 +323,7 @@ static void __exit pc8736x_gpio_cleanup(
platform_device_del(pdev);
platform_device_put(pdev);
+ superio_release(gate);
}
module_init(pc8736x_gpio_init);
_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
WARNING: multiple messages have this Message-ID (diff)
From: Jim Cromie <jim.cromie@gmail.com>
To: Linux kernel <linux-kernel@vger.kernel.org>,
LM Sensors <lm-sensors@lm-sensors.org>
Subject: [ patch .24-rc0 4/5 ] SuperIO locks coordinator - use in drivers/char/pc8736x-gpio
Date: Sun, 14 Oct 2007 23:08:31 -0600 [thread overview]
Message-ID: <4712F5CF.3030807@gmail.com> (raw)
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 <jim.cromie@gmail.com>
---
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.000000000 -0600
+++ hwmon-superio.old/drivers/char/Kconfig 2007-10-14 17:22:23.000000000 -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.000000000 -0600
+++ hwmon-superio.old/drivers/char/pc8736x_gpio.c 2007-10-14 17:22:23.000000000 -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_SID 0x20 /* SuperI/O ID Register */
-#define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */
-
-#define SIO_CF1 0x21 /* 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_UNIT 0x0D
#define SIO_TMS_UNIT 0x0E
+#define SIO_CF1 0x21 /* 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);
mutex_unlock(&pc8736x_gpio_config_lock);
+ superio_exit(gate);
return config;
}
@@ -259,40 +233,44 @@ static int __init pc8736x_gpio_init(void
rc = -ENODEV;
goto undo_platform_dev_alloc;
}
+ pc8736x_gpio_ops.dev = &pdev->dev;
+
dev_info(&pdev->dev, "NatSemi pc8736x GPIO Driver Initializing\n");
- if (!pc8736x_superio_present()) {
+ gate = superio_find(&where);
+ if (!gate) {
rc = -ENODEV;
- dev_err(&pdev->dev, "no device found\n");
+ dev_err(&pdev->dev, "no superio port found\n");
+ // goto err2;
goto undo_platform_dev_add;
}
- pc8736x_gpio_ops.dev = &pdev->dev;
/* Verify that chip and it's GPIO unit are both enabled.
My BIOS does this, so I take minimum action here
*/
- rc = superio_inb(SIO_CF1);
+ superio_enter(gate);
+ rc = superio_inb(gate, SIO_CF1);
if (!(rc & 0x01)) {
rc = -ENODEV;
dev_err(&pdev->dev, "device not enabled\n");
- goto undo_platform_dev_add;
+ goto undo_superio_enter;
}
device_select(SIO_GPIO_UNIT);
- if (!superio_inb(SIO_UNIT_ACT)) {
+ if (!superio_inb(gate, SIO_UNIT_ACT)) {
rc = -ENODEV;
dev_err(&pdev->dev, "GPIO unit not enabled\n");
- goto undo_platform_dev_add;
+ goto undo_superio_enter;
}
/* read the GPIO unit base addr that chip responds to */
- pc8736x_gpio_base = (superio_inb(SIO_BASE_HADDR) << 8
- | superio_inb(SIO_BASE_LADDR));
+ pc8736x_gpio_base = (superio_inb(gate, SIO_BASE_HADDR) << 8
+ | superio_inb(gate, SIO_BASE_LADDR));
if (!request_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE, DEVNAME)) {
rc = -ENODEV;
dev_err(&pdev->dev, "GPIO ioport %x busy\n",
pc8736x_gpio_base);
- goto undo_platform_dev_add;
+ goto undo_superio_enter;
}
dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base);
@@ -319,10 +297,14 @@ static int __init pc8736x_gpio_init(void
cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fileops);
cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT);
+ superio_exit(gate); /* no release, we need to stay registered */
return 0;
undo_request_region:
release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE);
+undo_superio_enter:
+ superio_exit(gate);
+ superio_release(gate);
undo_platform_dev_add:
platform_device_del(pdev);
undo_platform_dev_alloc:
@@ -341,6 +323,7 @@ static void __exit pc8736x_gpio_cleanup(
platform_device_del(pdev);
platform_device_put(pdev);
+ superio_release(gate);
}
module_init(pc8736x_gpio_init);
next reply other threads:[~2007-10-15 5:08 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-15 5:08 Jim Cromie [this message]
2007-10-15 5:08 ` [ patch .24-rc0 4/5 ] SuperIO locks coordinator - use in drivers/char/pc8736x-gpio Jim Cromie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4712F5CF.3030807@gmail.com \
--to=jim.cromie@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lm-sensors@lm-sensors.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.