All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing
@ 2010-03-23 14:12 ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 14:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Acquire the I/O region for the Super I/O chip while we're working on it.

Further alter the way multiple Super I/O addresses are probed for chips
such that errors in the probing process are passed on from the module
initialisation function.

Some code cleanup: properly using, previously defined, functions rather
than duplicating their code.
---
 drivers/hwmon/f71882fg.c |   38 +++++++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4230729..25e1cad 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg)
 static int superio_inw(int base, int reg)
 {
 	int val;
-	outb(reg++, base);
-	val = inb(base + 1) << 8;
-	outb(reg, base);
-	val |= inb(base + 1);
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
 	return val;
 }
 
@@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
 {
 	u16 val;
 
-	outb(reg++, data->addr + ADDR_REG_OFFSET);
-	val = inb(data->addr + DATA_REG_OFFSET) << 8;
-	outb(reg, data->addr + ADDR_REG_OFFSET);
-	val |= inb(data->addr + DATA_REG_OFFSET);
+	val  = f71882fg_read8(data, reg) << 8;
+	val |= f71882fg_read8(data, reg + 1);
 
 	return val;
 }
@@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
 
 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
 {
-	outb(reg++, data->addr + ADDR_REG_OFFSET);
-	outb(val >> 8, data->addr + DATA_REG_OFFSET);
-	outb(reg, data->addr + ADDR_REG_OFFSET);
-	outb(val & 255, data->addr + DATA_REG_OFFSET);
+	f71882fg_write8(data, reg,     val >> 8);
+	f71882fg_write8(data, reg + 1, val & 0xff);
 }
 
 static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
@@ -2184,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	int err = -ENODEV;
 	u16 devid;
 
+	/* Don't step on other driver's I/O space by accident */
+	if (!request_region(sioaddr, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)sioaddr);
+		return -EIO;
+	}
+
 	superio_enter(sioaddr);
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
@@ -2238,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
+	release_region(sioaddr, 2);
 	return err;
 }
 
@@ -2289,14 +2291,20 @@ exit_device_put:
 
 static int __init f71882fg_init(void)
 {
+	static const unsigned short addrs[] = { 0x2e, 0x4e };
 	int err = -ENODEV;
-	unsigned short address;
+	unsigned short address = /* shut up compiler */ 0;
 	struct f71882fg_sio_data sio_data;
+	int i;
 
 	memset(&sio_data, 0, sizeof(sio_data));
 
-	if (f71882fg_find(0x2e, &address, &sio_data) &&
-	    f71882fg_find(0x4e, &address, &sio_data))
+	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
+		err = f71882fg_find(addrs[i], &address, &sio_data);
+		if (err == 0)
+			break;
+	}
+	if (i == ARRAY_SIZE(addrs))
 		goto exit;
 
 	err = platform_driver_register(&f71882fg_driver);
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O regions
@ 2010-03-23 14:12 ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 14:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Acquire the I/O region for the Super I/O chip while we're working on it.

Further alter the way multiple Super I/O addresses are probed for chips
such that errors in the probing process are passed on from the module
initialisation function.

Some code cleanup: properly using, previously defined, functions rather
than duplicating their code.
---
 drivers/hwmon/f71882fg.c |   38 +++++++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4230729..25e1cad 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg)
 static int superio_inw(int base, int reg)
 {
 	int val;
-	outb(reg++, base);
-	val = inb(base + 1) << 8;
-	outb(reg, base);
-	val |= inb(base + 1);
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
 	return val;
 }
 
@@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
 {
 	u16 val;
 
-	outb(reg++, data->addr + ADDR_REG_OFFSET);
-	val = inb(data->addr + DATA_REG_OFFSET) << 8;
-	outb(reg, data->addr + ADDR_REG_OFFSET);
-	val |= inb(data->addr + DATA_REG_OFFSET);
+	val  = f71882fg_read8(data, reg) << 8;
+	val |= f71882fg_read8(data, reg + 1);
 
 	return val;
 }
@@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
 
 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
 {
-	outb(reg++, data->addr + ADDR_REG_OFFSET);
-	outb(val >> 8, data->addr + DATA_REG_OFFSET);
-	outb(reg, data->addr + ADDR_REG_OFFSET);
-	outb(val & 255, data->addr + DATA_REG_OFFSET);
+	f71882fg_write8(data, reg,     val >> 8);
+	f71882fg_write8(data, reg + 1, val & 0xff);
 }
 
 static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
@@ -2184,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	int err = -ENODEV;
 	u16 devid;
 
+	/* Don't step on other driver's I/O space by accident */
+	if (!request_region(sioaddr, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)sioaddr);
+		return -EIO;
+	}
+
 	superio_enter(sioaddr);
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
@@ -2238,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
+	release_region(sioaddr, 2);
 	return err;
 }
 
@@ -2289,14 +2291,20 @@ exit_device_put:
 
 static int __init f71882fg_init(void)
 {
+	static const unsigned short addrs[] = { 0x2e, 0x4e };
 	int err = -ENODEV;
-	unsigned short address;
+	unsigned short address = /* shut up compiler */ 0;
 	struct f71882fg_sio_data sio_data;
+	int i;
 
 	memset(&sio_data, 0, sizeof(sio_data));
 
-	if (f71882fg_find(0x2e, &address, &sio_data) &&
-	    f71882fg_find(0x4e, &address, &sio_data))
+	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
+		err = f71882fg_find(addrs[i], &address, &sio_data);
+		if (err = 0)
+			break;
+	}
+	if (i = ARRAY_SIZE(addrs))
 		goto exit;
 
 	err = platform_driver_register(&f71882fg_driver);
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing
  2010-03-23 14:12 ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O regions Giel van Schijndel
@ 2010-03-23 14:17   ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 14:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 874 bytes --]

On Tue, Mar 23, 2010 at 03:12:15PM +0100, Giel van Schijndel wrote:
> Acquire the I/O region for the Super I/O chip while we're working on it.
> 
> Further alter the way multiple Super I/O addresses are probed for chips
> such that errors in the probing process are passed on from the module
> initialisation function.
> 
> Some code cleanup: properly using, previously defined, functions rather
> than duplicating their code.

Oh yes, this in preparation for adding watchdog support for the Fintek
F71808E (very similar to the F71889) to this driver.

I'll be sending in a patch for adding sensor hardware monitor support
for the F71808E first (i.e. before the addition of watchdog support).

PS I'm using the watchdog API as described in
   Documentation/watchdog/watchdog-api.txt.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O
@ 2010-03-23 14:17   ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 14:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 874 bytes --]

On Tue, Mar 23, 2010 at 03:12:15PM +0100, Giel van Schijndel wrote:
> Acquire the I/O region for the Super I/O chip while we're working on it.
> 
> Further alter the way multiple Super I/O addresses are probed for chips
> such that errors in the probing process are passed on from the module
> initialisation function.
> 
> Some code cleanup: properly using, previously defined, functions rather
> than duplicating their code.

Oh yes, this in preparation for adding watchdog support for the Fintek
F71808E (very similar to the F71889) to this driver.

I'll be sending in a patch for adding sensor hardware monitor support
for the F71808E first (i.e. before the addition of watchdog support).

PS I'm using the watchdog API as described in
   Documentation/watchdog/watchdog-api.txt.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing
  2010-03-23 14:12 ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O regions Giel van Schijndel
@ 2010-03-23 23:01   ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:01 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 820 bytes --]

On Tue, Mar 23, 2010 at 03:12:15PM +0100, Giel van Schijndel wrote:
> Acquire the I/O region for the Super I/O chip while we're working on it.
> 
> Further alter the way multiple Super I/O addresses are probed for chips
> such that errors in the probing process are passed on from the module
> initialisation function.
> 
> Some code cleanup: properly using, previously defined, functions rather
> than duplicating their code.
> ---
>  drivers/hwmon/f71882fg.c |   38 +++++++++++++++++++++++---------------
>  1 files changed, 23 insertions(+), 15 deletions(-)

Sorry, forgot to sign off the commit message itself. So just to be sure
it's understood to be signed off on by myself:

Signed-off-by: Giel van Schijndel <me@mortis.eu>

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O
@ 2010-03-23 23:01   ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:01 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 820 bytes --]

On Tue, Mar 23, 2010 at 03:12:15PM +0100, Giel van Schijndel wrote:
> Acquire the I/O region for the Super I/O chip while we're working on it.
> 
> Further alter the way multiple Super I/O addresses are probed for chips
> such that errors in the probing process are passed on from the module
> initialisation function.
> 
> Some code cleanup: properly using, previously defined, functions rather
> than duplicating their code.
> ---
>  drivers/hwmon/f71882fg.c |   38 +++++++++++++++++++++++---------------
>  1 files changed, 23 insertions(+), 15 deletions(-)

Sorry, forgot to sign off the commit message itself. So just to be sure
it's understood to be signed off on by myself:

Signed-off-by: Giel van Schijndel <me@mortis.eu>

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-03-23 14:17   ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
@ 2010-03-23 23:12     ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Allow device probing to recognise the Fintek F71808E.

Sysfs interface:
 * Fan/pwm control is the same as for F71889FG
 * Temperature and voltage sensor handling is largely the same as for
   the F71889FG
  - Has one temperature sensor less (doesn't have temp3)
  - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
    what in7_input refers for F71889FG)

For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
such that it can largely be reused.
---
 Documentation/hwmon/f71882fg |    4 ++
 drivers/hwmon/Kconfig        |    6 ++--
 drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
 3 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index a7952c2..1a07fd6 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -2,6 +2,10 @@ Kernel driver f71882fg
 ======================
 
 Supported chips:
+  * Fintek F71808E
+    Prefix: 'f71808fg'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71858FG
     Prefix: 'f71858fg'
     Addresses scanned: none, address read from Super I/O config space
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e4595e6..7053608 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -332,11 +332,11 @@ config SENSORS_F71805F
 	  will be called f71805f.
 
 config SENSORS_F71882FG
-	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
+	tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
 	depends on EXPERIMENTAL
 	help
-	  If you say yes here you get support for hardware monitoring
-	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+	  If you say yes here you get support for hardware monitoring features
+	  of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
 	  F71889FG and F8000 Super-I/O chips.
 
 	  This driver can also be built as a module.  If so, the module
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 25e1cad..b290b87 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -45,6 +45,7 @@
 #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
 
 #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
@@ -96,9 +97,10 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
+	"f71808fg",
 	"f71858fg",
 	"f71862fg",
 	"f71882fg",
@@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 };
 
-/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
-static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
+/* In attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
 	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
 	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* In attr for the f71808fg */
+static struct sensor_device_attribute_2 f71808_in_attr[] = {
+	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
+	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
+	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
+	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
+	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
+	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
+	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
+	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
 	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
 	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 1),
@@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 		store_temp_beep, 0, 6),
 	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
 	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
+};
+
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 f71862_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
 	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 3),
@@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
 				data->temp_type[1] = 6;
 				break;
 			}
+		} else if (data->type == f71808fg) {
+			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
+			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
+
 		} else {
 			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
 			if ((reg2 & 0x03) == 0x01)
@@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
 
 	val /= 1000;
 
-	if (data->type == f71889fg)
+	if (data->type == f71889fg
+	 || data->type == f71808fg)
 		val = SENSORS_LIMIT(val, -128, 127);
 	else
 		val = SENSORS_LIMIT(val, 0, 127);
@@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			/* fall through! */
+		case f71808fg:
+			if (data->type == f71808fg) {
+				err = f71882fg_create_sysfs_files(pdev,
+						f71808_in_attr,
+						ARRAY_SIZE(f71808_in_attr));
+				if (err)
+					goto exit_unregister_sysfs;
+			}
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
@@ -2002,6 +2049,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 		case f71862fg:
 			err = (data->pwm_enable & 0x15) != 0x15;
 			break;
+		case f71808fg:
 		case f71882fg:
 		case f71889fg:
 			err = 0;
@@ -2047,6 +2095,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 					f8000_auto_pwm_attr,
 					ARRAY_SIZE(f8000_auto_pwm_attr));
 			break;
+		case f71808fg:
 		case f71889fg:
 			for (i = 0; i < nr_fans; i++) {
 				data->pwm_auto_point_mapping[i] =
@@ -2126,8 +2175,20 @@ static int f71882fg_remove(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			f71882fg_remove_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			/* fall through! */
+		case f71808fg:
+			if (data->type == f71808fg)
+				f71882fg_remove_sysfs_files(pdev,
+						f71808_in_attr,
+						ARRAY_SIZE(f71808_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			f71882fg_remove_sysfs_files(pdev,
@@ -2195,6 +2256,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
 	switch (devid) {
+	case SIO_F71808_ID:
+		sio_data->type = f71808fg;
+		break;
 	case SIO_F71858_ID:
 		sio_data->type = f71858fg;
 		break;
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for the
@ 2010-03-23 23:12     ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Allow device probing to recognise the Fintek F71808E.

Sysfs interface:
 * Fan/pwm control is the same as for F71889FG
 * Temperature and voltage sensor handling is largely the same as for
   the F71889FG
  - Has one temperature sensor less (doesn't have temp3)
  - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
    what in7_input refers for F71889FG)

For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
such that it can largely be reused.
---
 Documentation/hwmon/f71882fg |    4 ++
 drivers/hwmon/Kconfig        |    6 ++--
 drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
 3 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index a7952c2..1a07fd6 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -2,6 +2,10 @@ Kernel driver f71882fg
 ===========
 
 Supported chips:
+  * Fintek F71808E
+    Prefix: 'f71808fg'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71858FG
     Prefix: 'f71858fg'
     Addresses scanned: none, address read from Super I/O config space
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e4595e6..7053608 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -332,11 +332,11 @@ config SENSORS_F71805F
 	  will be called f71805f.
 
 config SENSORS_F71882FG
-	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
+	tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
 	depends on EXPERIMENTAL
 	help
-	  If you say yes here you get support for hardware monitoring
-	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+	  If you say yes here you get support for hardware monitoring features
+	  of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
 	  F71889FG and F8000 Super-I/O chips.
 
 	  This driver can also be built as a module.  If so, the module
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 25e1cad..b290b87 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -45,6 +45,7 @@
 #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
 
 #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
@@ -96,9 +97,10 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
+	"f71808fg",
 	"f71858fg",
 	"f71862fg",
 	"f71882fg",
@@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 };
 
-/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
-static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
+/* In attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
 	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
 	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* In attr for the f71808fg */
+static struct sensor_device_attribute_2 f71808_in_attr[] = {
+	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
+	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
+	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
+	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
+	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
+	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
+	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
+	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
 	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
 	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 1),
@@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 		store_temp_beep, 0, 6),
 	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
 	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
+};
+
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 f71862_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
 	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 3),
@@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
 				data->temp_type[1] = 6;
 				break;
 			}
+		} else if (data->type = f71808fg) {
+			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
+			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
+
 		} else {
 			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
 			if ((reg2 & 0x03) = 0x01)
@@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
 
 	val /= 1000;
 
-	if (data->type = f71889fg)
+	if (data->type = f71889fg
+	 || data->type = f71808fg)
 		val = SENSORS_LIMIT(val, -128, 127);
 	else
 		val = SENSORS_LIMIT(val, 0, 127);
@@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			/* fall through! */
+		case f71808fg:
+			if (data->type = f71808fg) {
+				err = f71882fg_create_sysfs_files(pdev,
+						f71808_in_attr,
+						ARRAY_SIZE(f71808_in_attr));
+				if (err)
+					goto exit_unregister_sysfs;
+			}
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
@@ -2002,6 +2049,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 		case f71862fg:
 			err = (data->pwm_enable & 0x15) != 0x15;
 			break;
+		case f71808fg:
 		case f71882fg:
 		case f71889fg:
 			err = 0;
@@ -2047,6 +2095,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 					f8000_auto_pwm_attr,
 					ARRAY_SIZE(f8000_auto_pwm_attr));
 			break;
+		case f71808fg:
 		case f71889fg:
 			for (i = 0; i < nr_fans; i++) {
 				data->pwm_auto_point_mapping[i] @@ -2126,8 +2175,20 @@ static int f71882fg_remove(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			f71882fg_remove_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			/* fall through! */
+		case f71808fg:
+			if (data->type = f71808fg)
+				f71882fg_remove_sysfs_files(pdev,
+						f71808_in_attr,
+						ARRAY_SIZE(f71808_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			f71882fg_remove_sysfs_files(pdev,
@@ -2195,6 +2256,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
 	switch (devid) {
+	case SIO_F71808_ID:
+		sio_data->type = f71808fg;
+		break;
 	case SIO_F71858_ID:
 		sio_data->type = f71858fg;
 		break;
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH 2/4] hwmon: f71882fg: prepare for addition of watchdog support
  2010-03-23 23:12     ` [lm-sensors] [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for the Giel van Schijndel
@ 2010-03-23 23:12       ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Rename the `address' variable that's used in some places to hwmon_addr
to indicate it refers to the hardware monitor (HWMON in datasheet)
"logical device" of the chip.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index b290b87..7b31e14 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2233,7 +2233,7 @@ static int f71882fg_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static int __init f71882fg_find(int sioaddr, unsigned short *address,
+static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
 	struct f71882fg_sio_data *sio_data)
 {
 	int err = -ENODEV;
@@ -2290,16 +2290,16 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		goto exit;
 	}
 
-	*address = superio_inw(sioaddr, SIO_REG_ADDR);
-	if (*address == 0) {
+	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
+	if (*hwmon_addr == 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
 		goto exit;
 	}
-	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
+	*hwmon_addr &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
 
 	err = 0;
 	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
-		f71882fg_names[sio_data->type],	(unsigned int)*address,
+		f71882fg_names[sio_data->type],	(unsigned int)*hwmon_addr,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
@@ -2307,17 +2307,17 @@ exit:
 	return err;
 }
 
-static int __init f71882fg_device_add(unsigned short address,
+static int __init f71882fg_device_add(unsigned short hwmon_addr,
 	const struct f71882fg_sio_data *sio_data)
 {
 	struct resource res = {
-		.start	= address,
-		.end	= address + REGION_LENGTH - 1,
+		.start	= hwmon_addr,
+		.end	= hwmon_addr + REGION_LENGTH - 1,
 		.flags	= IORESOURCE_IO,
 	};
 	int err;
 
-	f71882fg_pdev = platform_device_alloc(DRVNAME, address);
+	f71882fg_pdev = platform_device_alloc(DRVNAME, hwmon_addr);
 	if (!f71882fg_pdev)
 		return -ENOMEM;
 
@@ -2357,14 +2357,14 @@ static int __init f71882fg_init(void)
 {
 	static const unsigned short addrs[] = { 0x2e, 0x4e };
 	int err = -ENODEV;
-	unsigned short address = /* shut up compiler */ 0;
+	unsigned short hwmon_addr = /* shut up compiler */ 0;
 	struct f71882fg_sio_data sio_data;
 	int i;
 
 	memset(&sio_data, 0, sizeof(sio_data));
 
 	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
-		err = f71882fg_find(addrs[i], &address, &sio_data);
+		err = f71882fg_find(addrs[i], &hwmon_addr, &sio_data);
 		if (err == 0)
 			break;
 	}
@@ -2375,7 +2375,7 @@ static int __init f71882fg_init(void)
 	if (err)
 		goto exit;
 
-	err = f71882fg_device_add(address, &sio_data);
+	err = f71882fg_device_add(hwmon_addr, &sio_data);
 	if (err)
 		goto exit_driver;
 
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition of
@ 2010-03-23 23:12       ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Rename the `address' variable that's used in some places to hwmon_addr
to indicate it refers to the hardware monitor (HWMON in datasheet)
"logical device" of the chip.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index b290b87..7b31e14 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2233,7 +2233,7 @@ static int f71882fg_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static int __init f71882fg_find(int sioaddr, unsigned short *address,
+static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
 	struct f71882fg_sio_data *sio_data)
 {
 	int err = -ENODEV;
@@ -2290,16 +2290,16 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		goto exit;
 	}
 
-	*address = superio_inw(sioaddr, SIO_REG_ADDR);
-	if (*address = 0) {
+	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
+	if (*hwmon_addr = 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
 		goto exit;
 	}
-	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
+	*hwmon_addr &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
 
 	err = 0;
 	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
-		f71882fg_names[sio_data->type],	(unsigned int)*address,
+		f71882fg_names[sio_data->type],	(unsigned int)*hwmon_addr,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
@@ -2307,17 +2307,17 @@ exit:
 	return err;
 }
 
-static int __init f71882fg_device_add(unsigned short address,
+static int __init f71882fg_device_add(unsigned short hwmon_addr,
 	const struct f71882fg_sio_data *sio_data)
 {
 	struct resource res = {
-		.start	= address,
-		.end	= address + REGION_LENGTH - 1,
+		.start	= hwmon_addr,
+		.end	= hwmon_addr + REGION_LENGTH - 1,
 		.flags	= IORESOURCE_IO,
 	};
 	int err;
 
-	f71882fg_pdev = platform_device_alloc(DRVNAME, address);
+	f71882fg_pdev = platform_device_alloc(DRVNAME, hwmon_addr);
 	if (!f71882fg_pdev)
 		return -ENOMEM;
 
@@ -2357,14 +2357,14 @@ static int __init f71882fg_init(void)
 {
 	static const unsigned short addrs[] = { 0x2e, 0x4e };
 	int err = -ENODEV;
-	unsigned short address = /* shut up compiler */ 0;
+	unsigned short hwmon_addr = /* shut up compiler */ 0;
 	struct f71882fg_sio_data sio_data;
 	int i;
 
 	memset(&sio_data, 0, sizeof(sio_data));
 
 	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
-		err = f71882fg_find(addrs[i], &address, &sio_data);
+		err = f71882fg_find(addrs[i], &hwmon_addr, &sio_data);
 		if (err = 0)
 			break;
 	}
@@ -2375,7 +2375,7 @@ static int __init f71882fg_init(void)
 	if (err)
 		goto exit;
 
-	err = f71882fg_device_add(address, &sio_data);
+	err = f71882fg_device_add(hwmon_addr, &sio_data);
 	if (err)
 		goto exit_driver;
 
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH 3/4] hwmon: f71882fg: add watchdog detection code
  2010-03-23 23:12       ` [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition of Giel van Schijndel
@ 2010-03-23 23:12         ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Factor out code for detecting the hardware monitor into a separate
function. Then add a function for detecting the watchdog.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   74 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 58 insertions(+), 16 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7b31e14..8006271 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2233,6 +2233,54 @@ static int f71882fg_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int __init f71882fg_find_watchdog(int sioaddr,
+	const struct f71882fg_sio_data *sio_data)
+{
+	switch (sio_data->type) {
+	case f71808fg:
+		break;
+
+	case f71862fg:
+	case f71882fg:
+	case f71889fg:
+		/* These have a watchdog, though it isn't implemented (yet). */
+		return -ENOSYS;
+
+	case f71858fg:
+	default:
+		/*
+		 * Confirmed (by datasheet) not to have a watchdog. That is,
+		 * except for chips matched by the 'default' label of course.
+		 */
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int __init f71882fg_find_hwmon(int sioaddr, unsigned short *hwmon_addr,
+	struct f71882fg_sio_data *sio_data)
+{
+	if (sio_data->type == f71858fg)
+		superio_select(sioaddr, SIO_F71858FG_LD_HWM);
+	else
+		superio_select(sioaddr, SIO_F71882FG_LD_HWM);
+
+	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
+		printk(KERN_WARNING DRVNAME ": Device not activated\n");
+		return -ENODEV;
+	}
+
+	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
+	if (*hwmon_addr == 0) {
+		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+		return -ENODEV;
+	}
+	*hwmon_addr &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
+
+	return 0;
+}
+
 static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
 	struct f71882fg_sio_data *sio_data)
 {
@@ -2280,27 +2328,21 @@ static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
 		goto exit;
 	}
 
-	if (sio_data->type == f71858fg)
-		superio_select(sioaddr, SIO_F71858FG_LD_HWM);
-	else
-		superio_select(sioaddr, SIO_F71882FG_LD_HWM);
-
-	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
-		printk(KERN_WARNING DRVNAME ": Device not activated\n");
-		goto exit;
-	}
-
-	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
-	if (*hwmon_addr == 0) {
-		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+	err = f71882fg_find_hwmon(sioaddr, hwmon_addr, sio_data);
+	if (err)
 		goto exit;
-	}
-	*hwmon_addr &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
 
-	err = 0;
 	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
 		f71882fg_names[sio_data->type],	(unsigned int)*hwmon_addr,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
+
+	err = f71882fg_find_watchdog(sioaddr, sio_data);
+	if (err == 0)
+		printk(KERN_INFO DRVNAME ": has supported watchdog\n");
+	else if (err != -ENODEV && err != -ENOSYS)
+		goto exit;
+
+	err = 0;
 exit:
 	superio_exit(sioaddr);
 	release_region(sioaddr, 2);
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH 3/4] hwmon: f71882fg: add watchdog detection
@ 2010-03-23 23:12         ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Factor out code for detecting the hardware monitor into a separate
function. Then add a function for detecting the watchdog.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   74 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 58 insertions(+), 16 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7b31e14..8006271 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2233,6 +2233,54 @@ static int f71882fg_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int __init f71882fg_find_watchdog(int sioaddr,
+	const struct f71882fg_sio_data *sio_data)
+{
+	switch (sio_data->type) {
+	case f71808fg:
+		break;
+
+	case f71862fg:
+	case f71882fg:
+	case f71889fg:
+		/* These have a watchdog, though it isn't implemented (yet). */
+		return -ENOSYS;
+
+	case f71858fg:
+	default:
+		/*
+		 * Confirmed (by datasheet) not to have a watchdog. That is,
+		 * except for chips matched by the 'default' label of course.
+		 */
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int __init f71882fg_find_hwmon(int sioaddr, unsigned short *hwmon_addr,
+	struct f71882fg_sio_data *sio_data)
+{
+	if (sio_data->type = f71858fg)
+		superio_select(sioaddr, SIO_F71858FG_LD_HWM);
+	else
+		superio_select(sioaddr, SIO_F71882FG_LD_HWM);
+
+	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
+		printk(KERN_WARNING DRVNAME ": Device not activated\n");
+		return -ENODEV;
+	}
+
+	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
+	if (*hwmon_addr = 0) {
+		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+		return -ENODEV;
+	}
+	*hwmon_addr &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
+
+	return 0;
+}
+
 static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
 	struct f71882fg_sio_data *sio_data)
 {
@@ -2280,27 +2328,21 @@ static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
 		goto exit;
 	}
 
-	if (sio_data->type = f71858fg)
-		superio_select(sioaddr, SIO_F71858FG_LD_HWM);
-	else
-		superio_select(sioaddr, SIO_F71882FG_LD_HWM);
-
-	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
-		printk(KERN_WARNING DRVNAME ": Device not activated\n");
-		goto exit;
-	}
-
-	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
-	if (*hwmon_addr = 0) {
-		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+	err = f71882fg_find_hwmon(sioaddr, hwmon_addr, sio_data);
+	if (err)
 		goto exit;
-	}
-	*hwmon_addr &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
 
-	err = 0;
 	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
 		f71882fg_names[sio_data->type],	(unsigned int)*hwmon_addr,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
+
+	err = f71882fg_find_watchdog(sioaddr, sio_data);
+	if (err = 0)
+		printk(KERN_INFO DRVNAME ": has supported watchdog\n");
+	else if (err != -ENODEV && err != -ENOSYS)
+		goto exit;
+
+	err = 0;
 exit:
 	superio_exit(sioaddr);
 	release_region(sioaddr, 2);
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-23 23:12         ` [lm-sensors] [PATCH 3/4] hwmon: f71882fg: add watchdog detection Giel van Schijndel
@ 2010-03-23 23:12           ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Implement the watchdog API for the Fintek F71808E.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |  553 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 553 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 8006271..3604613 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -26,14 +26,19 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
+#include <linux/miscdevice.h>
 #include <linux/mutex.h>
+#include <linux/notifier.h>
 #include <linux/io.h>
 #include <linux/acpi.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
 
 #define DRVNAME "f71882fg"
 
 #define SIO_F71858FG_LD_HWM	0x02	/* Hardware monitor logical device */
 #define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device */
+#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
 #define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
 #define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
 
@@ -91,12 +96,52 @@
 
 #define	F71882FG_REG_START		0x01
 
+#define F71808FG_REG_WDO_CONF		0xf0
+#define F71808FG_REG_WDT_CONF		0xf5
+#define F71808FG_REG_WD_TIME		0xf6
+
+#define F71808FG_FLAG_WDOUT_EN		7
+
+#define F71808FG_FLAG_WDTMOUT_STS	5
+#define F71808FG_FLAG_WD_EN		5
+#define F71808FG_FLAG_WD_PULSE		4
+#define F71808FG_FLAG_WD_UNIT		3
+
 #define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */
 
+/* Default values */
+#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
+#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
+#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
+					   watchdog signal */
+
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
+static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
+static int timeout = 60;	/* default timeout in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in seconds. 1<= timeout <="
+			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
+			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
+module_param(pulse_width, uint, 0);
+MODULE_PARM_DESC(pulse_width,
+	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
+			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+static int start_withtimeout = 0;
+module_param(start_withtimeout, uint, 0);
+MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
+	" given initial timeout. Zero (default) disables this feature.");
+
 enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
@@ -113,6 +158,9 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
+static inline void superio_outb(int base, int reg, u8 val);
+static inline void superio_set_bit(int base, int reg, int bit);
+static inline void superio_clear_bit(int base, int reg, int bit);
 static inline void superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
@@ -162,6 +210,24 @@ struct f71882fg_data {
 	s8	pwm_auto_point_temp[4][4];
 };
 
+struct watchdog_data {
+	unsigned short	sioaddr;
+	enum chips	type;
+	unsigned long	opened;
+	struct mutex	lock;
+	char		expect_close;
+	struct watchdog_info ident;
+
+	unsigned short	timeout;
+	u8		timer_val;	/* content for the wd_time register */
+	char		minutes_mode;
+	u8		pulse_val;	/* pulse width flag */
+	char		pulse_mode;	/* enable pulse output mode? */
+	char		caused_reboot;	/* last reboot was by the watchdog */
+};
+
+static struct watchdog_data *watchdog;
+
 /* Sysfs in */
 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
 	char *buf);
@@ -883,6 +949,26 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
+static inline void superio_outb(int base, int reg, u8 val)
+{
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static inline void superio_set_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__set_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__clear_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
 static inline void superio_enter(int base)
 {
 	/* according to the datasheet the key must be send twice! */
@@ -1941,6 +2027,430 @@ static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
 		device_remove_file(&pdev->dev, &attr[i].dev_attr);
 }
 
+static int watchdog_set_timeout(int timeout)
+{
+	if (!watchdog)
+		return -ENODEV;
+
+	if (timeout <= 0
+	 || timeout >  max_timeout) {
+		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&watchdog->lock);
+
+	watchdog->timeout = timeout;
+	if (timeout > 0xff) {
+		watchdog->timer_val = DIV_ROUND_UP(timeout, 60);
+		watchdog->minutes_mode = true;
+	} else {
+		watchdog->timer_val = timeout;
+		watchdog->minutes_mode = false;
+	}
+
+	mutex_unlock(&watchdog->lock);
+
+	return 0;
+}
+
+static int watchdog_set_pulse_width(unsigned int pw)
+{
+	int err = 0;
+
+	if (!watchdog)
+		return -ENODEV;
+
+	mutex_lock(&watchdog->lock);
+
+	if        (pw <=    1) {
+		watchdog->pulse_val = 0;
+	} else if (pw <=   25) {
+		watchdog->pulse_val = 1;
+	} else if (pw <=  125) {
+		watchdog->pulse_val = 2;
+	} else if (pw <= 5000) {
+		watchdog->pulse_val = 3;
+	} else {
+		printk(KERN_ERR DRVNAME ": watchdog pulse width out of range\n");
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+
+	watchdog->pulse_mode = pw;
+
+exit_unlock:
+	mutex_unlock(&watchdog->lock);
+	return err;
+}
+
+static int watchdog_keepalive(void)
+{
+	if (!watchdog)
+		return -ENODEV;
+
+	mutex_lock(&watchdog->lock);
+	superio_enter(watchdog->sioaddr);
+
+	if (watchdog->minutes_mode)
+		/* select minutes for timer units */
+		superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+	else
+		/* select seconds for timer units */
+		superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+
+	/* Set timer value */
+	superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
+			   watchdog->timeout);
+
+	superio_exit(watchdog->sioaddr);
+	mutex_unlock(&watchdog->lock);
+	return 0;
+}
+
+static int watchdog_start(void)
+{
+	/* Make sure we don't die as soon as the watchdog is enabled below */
+	int err = watchdog_keepalive();
+	if (err)
+		return err;
+
+	mutex_lock(&watchdog->lock);
+	superio_enter(watchdog->sioaddr);
+
+	/* Watchdog pin configuration */
+	switch (watchdog->type) {
+	case f71808fg:
+		/* Set ping 21 to GPIO23/WDTRST#, then to WDTRST# */
+		superio_clear_bit(watchdog->sioaddr, 0x2a, 3);
+		superio_clear_bit(watchdog->sioaddr, 0x2b, 3);
+		break;
+
+	default:
+		/* 'default' label to shut up the compiler and catch programmer errors */
+		err = -ENODEV;
+		goto exit_unlock;
+	}
+
+	superio_select(watchdog->sioaddr, SIO_F71808FG_LD_WDT);
+	superio_set_bit(watchdog->sioaddr, SIO_REG_ENABLE, 0);
+	superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDO_CONF,
+			F71808FG_FLAG_WDOUT_EN);
+
+	superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	if (watchdog->pulse_mode) {
+		/* Select "pulse" output mode with given duration */
+		u8 wdt_conf = superio_inb(watchdog->sioaddr,
+				F71808FG_REG_WDT_CONF);
+
+		/* Set WD_PSWIDTH bits (1:0) */
+		wdt_conf = (wdt_conf & 0xfc) | (watchdog->pulse_val & 0x03);
+		/* Set WD_PULSE to "pulse" mode */
+		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
+
+		superio_outb(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+				wdt_conf);
+	} else {
+		/* Select "level" output mode */
+		superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_PULSE);
+	}
+
+exit_unlock:
+	superio_exit(watchdog->sioaddr);
+	mutex_unlock(&watchdog->lock);
+
+	return err;
+}
+
+static int watchdog_stop(void)
+{
+	if (!watchdog)
+		return -ENODEV;
+
+	mutex_lock(&watchdog->lock);
+	superio_enter(watchdog->sioaddr);
+
+	superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog->sioaddr);
+	mutex_unlock(&watchdog->lock);
+
+	return 0;
+}
+
+static int watchdog_get_status(void)
+{
+	int status = 0;
+
+	if (!watchdog)
+		return -ENODEV;
+
+	mutex_lock(&watchdog->lock);
+	status = (watchdog->caused_reboot) ? WDIOF_CARDRESET : 0;
+	mutex_unlock(&watchdog->lock);
+
+	return status;
+}
+
+/* /dev/watchdog api */
+
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	int err;
+
+	/* If the watchdog is alive we don't need to start it again */
+	if (test_and_set_bit(0, &watchdog->opened))
+		return -EBUSY;
+
+	err = watchdog_start();
+	if (err) {
+		clear_bit(0, &watchdog->opened);
+		return err;
+	}
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	watchdog->expect_close = 0;
+	return nonseekable_open(inode, file);
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &watchdog->opened);
+
+	if (!watchdog->expect_close) {
+		watchdog_keepalive();
+		printk(KERN_CRIT DRVNAME
+			": Unexpected close, not stopping watchdog!\n");
+	} else if (!nowayout) {
+		watchdog_stop();
+	}
+	return 0;
+}
+
+/*
+ *      watchdog_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t watchdog_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			bool expect_close = false;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				expect_close = (c == 'V');
+			}
+
+			/* Lock to properly order writes across fork()ed processes */
+			mutex_lock(&watchdog->lock);
+			watchdog->expect_close = expect_close;
+			mutex_unlock(&watchdog->lock);
+		}
+
+		/* someone wrote to us, we should restart timer */
+		watchdog_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      watchdog_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+static long watchdog_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	int status;
+	int new_options;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &watchdog->ident,
+			sizeof(watchdog->ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		status = watchdog_get_status();
+		if (status < 0)
+			return status;
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD) {
+			watchdog_stop();
+		}
+
+		if (new_options & WDIOS_ENABLECARD)
+			return watchdog_start();
+
+
+	case WDIOC_KEEPALIVE:
+		watchdog_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (watchdog_set_timeout(new_timeout))
+			return -EINVAL;
+
+		watchdog_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(watchdog->timeout, uarg.i);
+
+	default:
+		return -ENOTTY;
+
+	}
+}
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		watchdog_stop();
+	return NOTIFY_DONE;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= watchdog_open,
+	.release	= watchdog_release,
+	.write		= watchdog_write,
+	.unlocked_ioctl	= watchdog_ioctl,
+};
+
+static struct miscdevice watchdog_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &watchdog_fops,
+};
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+static int __init watchdog_init(void)
+{
+	int err = 0;
+
+	if (!request_region(watchdog->sioaddr, 2,
+			watchdog->ident.identity)) {
+		printk(KERN_ERR DRVNAME
+			": I/O address 0x%04x already in use\n",
+				(int)watchdog->sioaddr);
+		return -EIO;
+	}
+
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err)
+		goto exit_region;
+
+	err = misc_register(&watchdog_miscdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME
+			": cannot register miscdev on minor=%d\n",
+				watchdog_miscdev.minor);
+		goto exit_reboot;
+	}
+
+	if (start_withtimeout) {
+		if (start_withtimeout <= 0
+		 || start_withtimeout >  max_timeout) {
+			printk(KERN_ERR DRVNAME ": watchdog starting timeout out of range\n");
+			err = -EINVAL;
+			goto exit_reboot;
+		}
+
+		err = watchdog_start();
+		if (err) {
+			printk(KERN_ERR DRVNAME
+				": cannot start watchdog timer\n");
+			goto exit_reboot;
+		}
+
+		mutex_lock(&watchdog->lock);
+		superio_enter(watchdog->sioaddr);
+
+		if (start_withtimeout > 0xff) {
+			/* select minutes for timer units */
+			superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+					F71808FG_FLAG_WD_UNIT);
+			superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
+					   DIV_ROUND_UP(start_withtimeout, 60));
+		} else {
+			/* select seconds for timer units */
+			superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+					F71808FG_FLAG_WD_UNIT);
+			superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
+					   start_withtimeout);
+		}
+
+		superio_exit(watchdog->sioaddr);
+		mutex_unlock(&watchdog->lock);
+
+		if (nowayout)
+			__module_get(THIS_MODULE);
+
+		printk(KERN_INFO DRVNAME
+			": watchdog started with initial timeout of %d seconds!\n",
+			start_withtimeout);
+	}
+
+	return 0;
+
+exit_reboot:
+	unregister_reboot_notifier(&watchdog_notifier);
+exit_region:
+	release_region(watchdog->sioaddr, 2);
+
+	return err;
+}
+
 static int __devinit f71882fg_probe(struct platform_device *pdev)
 {
 	struct f71882fg_data *data;
@@ -2236,8 +2746,32 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find_watchdog(int sioaddr,
 	const struct f71882fg_sio_data *sio_data)
 {
+	int err = 0;
+
 	switch (sio_data->type) {
 	case f71808fg:
+		watchdog = kzalloc(sizeof(*watchdog), GFP_KERNEL);
+		if (!watchdog)
+			return -ENOMEM;
+
+		mutex_init(&watchdog->lock);
+		watchdog->sioaddr = sioaddr;
+		watchdog->type = sio_data->type;
+
+		watchdog->ident.options = WDIOC_SETTIMEOUT
+					| WDIOF_MAGICCLOSE
+					| WDIOF_KEEPALIVEPING;
+		snprintf(watchdog->ident.identity,
+			sizeof(watchdog->ident.identity), "%s watchdog",
+			f71882fg_names[watchdog->type]);
+
+		err = watchdog_set_timeout(timeout);
+		if (err)
+			goto exit_alloc;
+		err = watchdog_set_pulse_width(pulse_width);
+		if (err)
+			goto exit_alloc;
+
 		break;
 
 	case f71862fg:
@@ -2256,6 +2790,12 @@ static int __init f71882fg_find_watchdog(int sioaddr,
 	}
 
 	return 0;
+
+exit_alloc:
+	kfree(watchdog);
+	watchdog = NULL;
+
+	return err;
 }
 
 static int __init f71882fg_find_hwmon(int sioaddr, unsigned short *hwmon_addr,
@@ -2421,6 +2961,12 @@ static int __init f71882fg_init(void)
 	if (err)
 		goto exit_driver;
 
+	if (watchdog) {
+		err = watchdog_init();
+		if (err)
+			goto exit_driver;
+	}
+
 	return 0;
 
 exit_driver:
@@ -2433,6 +2979,13 @@ static void __exit f71882fg_exit(void)
 {
 	platform_device_unregister(f71882fg_pdev);
 	platform_driver_unregister(&f71882fg_driver);
+
+	if (watchdog) {
+		watchdog_stop();
+		misc_deregister(&watchdog_miscdev);
+		unregister_reboot_notifier(&watchdog_notifier);
+		release_region(watchdog->sioaddr, 2);
+	}
 }
 
 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API
@ 2010-03-23 23:12           ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Implement the watchdog API for the Fintek F71808E.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |  553 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 553 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 8006271..3604613 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -26,14 +26,19 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
+#include <linux/miscdevice.h>
 #include <linux/mutex.h>
+#include <linux/notifier.h>
 #include <linux/io.h>
 #include <linux/acpi.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
 
 #define DRVNAME "f71882fg"
 
 #define SIO_F71858FG_LD_HWM	0x02	/* Hardware monitor logical device */
 #define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device */
+#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
 #define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
 #define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
 
@@ -91,12 +96,52 @@
 
 #define	F71882FG_REG_START		0x01
 
+#define F71808FG_REG_WDO_CONF		0xf0
+#define F71808FG_REG_WDT_CONF		0xf5
+#define F71808FG_REG_WD_TIME		0xf6
+
+#define F71808FG_FLAG_WDOUT_EN		7
+
+#define F71808FG_FLAG_WDTMOUT_STS	5
+#define F71808FG_FLAG_WD_EN		5
+#define F71808FG_FLAG_WD_PULSE		4
+#define F71808FG_FLAG_WD_UNIT		3
+
 #define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */
 
+/* Default values */
+#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
+#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
+#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
+					   watchdog signal */
+
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
+static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
+static int timeout = 60;	/* default timeout in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in seconds. 1<= timeout <="
+			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
+			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
+module_param(pulse_width, uint, 0);
+MODULE_PARM_DESC(pulse_width,
+	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
+			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+static int start_withtimeout = 0;
+module_param(start_withtimeout, uint, 0);
+MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
+	" given initial timeout. Zero (default) disables this feature.");
+
 enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
@@ -113,6 +158,9 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
+static inline void superio_outb(int base, int reg, u8 val);
+static inline void superio_set_bit(int base, int reg, int bit);
+static inline void superio_clear_bit(int base, int reg, int bit);
 static inline void superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
@@ -162,6 +210,24 @@ struct f71882fg_data {
 	s8	pwm_auto_point_temp[4][4];
 };
 
+struct watchdog_data {
+	unsigned short	sioaddr;
+	enum chips	type;
+	unsigned long	opened;
+	struct mutex	lock;
+	char		expect_close;
+	struct watchdog_info ident;
+
+	unsigned short	timeout;
+	u8		timer_val;	/* content for the wd_time register */
+	char		minutes_mode;
+	u8		pulse_val;	/* pulse width flag */
+	char		pulse_mode;	/* enable pulse output mode? */
+	char		caused_reboot;	/* last reboot was by the watchdog */
+};
+
+static struct watchdog_data *watchdog;
+
 /* Sysfs in */
 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
 	char *buf);
@@ -883,6 +949,26 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
+static inline void superio_outb(int base, int reg, u8 val)
+{
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static inline void superio_set_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__set_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__clear_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
 static inline void superio_enter(int base)
 {
 	/* according to the datasheet the key must be send twice! */
@@ -1941,6 +2027,430 @@ static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
 		device_remove_file(&pdev->dev, &attr[i].dev_attr);
 }
 
+static int watchdog_set_timeout(int timeout)
+{
+	if (!watchdog)
+		return -ENODEV;
+
+	if (timeout <= 0
+	 || timeout >  max_timeout) {
+		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&watchdog->lock);
+
+	watchdog->timeout = timeout;
+	if (timeout > 0xff) {
+		watchdog->timer_val = DIV_ROUND_UP(timeout, 60);
+		watchdog->minutes_mode = true;
+	} else {
+		watchdog->timer_val = timeout;
+		watchdog->minutes_mode = false;
+	}
+
+	mutex_unlock(&watchdog->lock);
+
+	return 0;
+}
+
+static int watchdog_set_pulse_width(unsigned int pw)
+{
+	int err = 0;
+
+	if (!watchdog)
+		return -ENODEV;
+
+	mutex_lock(&watchdog->lock);
+
+	if        (pw <=    1) {
+		watchdog->pulse_val = 0;
+	} else if (pw <=   25) {
+		watchdog->pulse_val = 1;
+	} else if (pw <=  125) {
+		watchdog->pulse_val = 2;
+	} else if (pw <= 5000) {
+		watchdog->pulse_val = 3;
+	} else {
+		printk(KERN_ERR DRVNAME ": watchdog pulse width out of range\n");
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+
+	watchdog->pulse_mode = pw;
+
+exit_unlock:
+	mutex_unlock(&watchdog->lock);
+	return err;
+}
+
+static int watchdog_keepalive(void)
+{
+	if (!watchdog)
+		return -ENODEV;
+
+	mutex_lock(&watchdog->lock);
+	superio_enter(watchdog->sioaddr);
+
+	if (watchdog->minutes_mode)
+		/* select minutes for timer units */
+		superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+	else
+		/* select seconds for timer units */
+		superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+
+	/* Set timer value */
+	superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
+			   watchdog->timeout);
+
+	superio_exit(watchdog->sioaddr);
+	mutex_unlock(&watchdog->lock);
+	return 0;
+}
+
+static int watchdog_start(void)
+{
+	/* Make sure we don't die as soon as the watchdog is enabled below */
+	int err = watchdog_keepalive();
+	if (err)
+		return err;
+
+	mutex_lock(&watchdog->lock);
+	superio_enter(watchdog->sioaddr);
+
+	/* Watchdog pin configuration */
+	switch (watchdog->type) {
+	case f71808fg:
+		/* Set ping 21 to GPIO23/WDTRST#, then to WDTRST# */
+		superio_clear_bit(watchdog->sioaddr, 0x2a, 3);
+		superio_clear_bit(watchdog->sioaddr, 0x2b, 3);
+		break;
+
+	default:
+		/* 'default' label to shut up the compiler and catch programmer errors */
+		err = -ENODEV;
+		goto exit_unlock;
+	}
+
+	superio_select(watchdog->sioaddr, SIO_F71808FG_LD_WDT);
+	superio_set_bit(watchdog->sioaddr, SIO_REG_ENABLE, 0);
+	superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDO_CONF,
+			F71808FG_FLAG_WDOUT_EN);
+
+	superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	if (watchdog->pulse_mode) {
+		/* Select "pulse" output mode with given duration */
+		u8 wdt_conf = superio_inb(watchdog->sioaddr,
+				F71808FG_REG_WDT_CONF);
+
+		/* Set WD_PSWIDTH bits (1:0) */
+		wdt_conf = (wdt_conf & 0xfc) | (watchdog->pulse_val & 0x03);
+		/* Set WD_PULSE to "pulse" mode */
+		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
+
+		superio_outb(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+				wdt_conf);
+	} else {
+		/* Select "level" output mode */
+		superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_PULSE);
+	}
+
+exit_unlock:
+	superio_exit(watchdog->sioaddr);
+	mutex_unlock(&watchdog->lock);
+
+	return err;
+}
+
+static int watchdog_stop(void)
+{
+	if (!watchdog)
+		return -ENODEV;
+
+	mutex_lock(&watchdog->lock);
+	superio_enter(watchdog->sioaddr);
+
+	superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog->sioaddr);
+	mutex_unlock(&watchdog->lock);
+
+	return 0;
+}
+
+static int watchdog_get_status(void)
+{
+	int status = 0;
+
+	if (!watchdog)
+		return -ENODEV;
+
+	mutex_lock(&watchdog->lock);
+	status = (watchdog->caused_reboot) ? WDIOF_CARDRESET : 0;
+	mutex_unlock(&watchdog->lock);
+
+	return status;
+}
+
+/* /dev/watchdog api */
+
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	int err;
+
+	/* If the watchdog is alive we don't need to start it again */
+	if (test_and_set_bit(0, &watchdog->opened))
+		return -EBUSY;
+
+	err = watchdog_start();
+	if (err) {
+		clear_bit(0, &watchdog->opened);
+		return err;
+	}
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	watchdog->expect_close = 0;
+	return nonseekable_open(inode, file);
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &watchdog->opened);
+
+	if (!watchdog->expect_close) {
+		watchdog_keepalive();
+		printk(KERN_CRIT DRVNAME
+			": Unexpected close, not stopping watchdog!\n");
+	} else if (!nowayout) {
+		watchdog_stop();
+	}
+	return 0;
+}
+
+/*
+ *      watchdog_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t watchdog_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			bool expect_close = false;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				expect_close = (c = 'V');
+			}
+
+			/* Lock to properly order writes across fork()ed processes */
+			mutex_lock(&watchdog->lock);
+			watchdog->expect_close = expect_close;
+			mutex_unlock(&watchdog->lock);
+		}
+
+		/* someone wrote to us, we should restart timer */
+		watchdog_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      watchdog_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+static long watchdog_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	int status;
+	int new_options;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &watchdog->ident,
+			sizeof(watchdog->ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		status = watchdog_get_status();
+		if (status < 0)
+			return status;
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD) {
+			watchdog_stop();
+		}
+
+		if (new_options & WDIOS_ENABLECARD)
+			return watchdog_start();
+
+
+	case WDIOC_KEEPALIVE:
+		watchdog_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (watchdog_set_timeout(new_timeout))
+			return -EINVAL;
+
+		watchdog_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(watchdog->timeout, uarg.i);
+
+	default:
+		return -ENOTTY;
+
+	}
+}
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code = SYS_DOWN || code = SYS_HALT)
+		watchdog_stop();
+	return NOTIFY_DONE;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= watchdog_open,
+	.release	= watchdog_release,
+	.write		= watchdog_write,
+	.unlocked_ioctl	= watchdog_ioctl,
+};
+
+static struct miscdevice watchdog_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &watchdog_fops,
+};
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+static int __init watchdog_init(void)
+{
+	int err = 0;
+
+	if (!request_region(watchdog->sioaddr, 2,
+			watchdog->ident.identity)) {
+		printk(KERN_ERR DRVNAME
+			": I/O address 0x%04x already in use\n",
+				(int)watchdog->sioaddr);
+		return -EIO;
+	}
+
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err)
+		goto exit_region;
+
+	err = misc_register(&watchdog_miscdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME
+			": cannot register miscdev on minor=%d\n",
+				watchdog_miscdev.minor);
+		goto exit_reboot;
+	}
+
+	if (start_withtimeout) {
+		if (start_withtimeout <= 0
+		 || start_withtimeout >  max_timeout) {
+			printk(KERN_ERR DRVNAME ": watchdog starting timeout out of range\n");
+			err = -EINVAL;
+			goto exit_reboot;
+		}
+
+		err = watchdog_start();
+		if (err) {
+			printk(KERN_ERR DRVNAME
+				": cannot start watchdog timer\n");
+			goto exit_reboot;
+		}
+
+		mutex_lock(&watchdog->lock);
+		superio_enter(watchdog->sioaddr);
+
+		if (start_withtimeout > 0xff) {
+			/* select minutes for timer units */
+			superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+					F71808FG_FLAG_WD_UNIT);
+			superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
+					   DIV_ROUND_UP(start_withtimeout, 60));
+		} else {
+			/* select seconds for timer units */
+			superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
+					F71808FG_FLAG_WD_UNIT);
+			superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
+					   start_withtimeout);
+		}
+
+		superio_exit(watchdog->sioaddr);
+		mutex_unlock(&watchdog->lock);
+
+		if (nowayout)
+			__module_get(THIS_MODULE);
+
+		printk(KERN_INFO DRVNAME
+			": watchdog started with initial timeout of %d seconds!\n",
+			start_withtimeout);
+	}
+
+	return 0;
+
+exit_reboot:
+	unregister_reboot_notifier(&watchdog_notifier);
+exit_region:
+	release_region(watchdog->sioaddr, 2);
+
+	return err;
+}
+
 static int __devinit f71882fg_probe(struct platform_device *pdev)
 {
 	struct f71882fg_data *data;
@@ -2236,8 +2746,32 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find_watchdog(int sioaddr,
 	const struct f71882fg_sio_data *sio_data)
 {
+	int err = 0;
+
 	switch (sio_data->type) {
 	case f71808fg:
+		watchdog = kzalloc(sizeof(*watchdog), GFP_KERNEL);
+		if (!watchdog)
+			return -ENOMEM;
+
+		mutex_init(&watchdog->lock);
+		watchdog->sioaddr = sioaddr;
+		watchdog->type = sio_data->type;
+
+		watchdog->ident.options = WDIOC_SETTIMEOUT
+					| WDIOF_MAGICCLOSE
+					| WDIOF_KEEPALIVEPING;
+		snprintf(watchdog->ident.identity,
+			sizeof(watchdog->ident.identity), "%s watchdog",
+			f71882fg_names[watchdog->type]);
+
+		err = watchdog_set_timeout(timeout);
+		if (err)
+			goto exit_alloc;
+		err = watchdog_set_pulse_width(pulse_width);
+		if (err)
+			goto exit_alloc;
+
 		break;
 
 	case f71862fg:
@@ -2256,6 +2790,12 @@ static int __init f71882fg_find_watchdog(int sioaddr,
 	}
 
 	return 0;
+
+exit_alloc:
+	kfree(watchdog);
+	watchdog = NULL;
+
+	return err;
 }
 
 static int __init f71882fg_find_hwmon(int sioaddr, unsigned short *hwmon_addr,
@@ -2421,6 +2961,12 @@ static int __init f71882fg_init(void)
 	if (err)
 		goto exit_driver;
 
+	if (watchdog) {
+		err = watchdog_init();
+		if (err)
+			goto exit_driver;
+	}
+
 	return 0;
 
 exit_driver:
@@ -2433,6 +2979,13 @@ static void __exit f71882fg_exit(void)
 {
 	platform_device_unregister(f71882fg_pdev);
 	platform_driver_unregister(&f71882fg_driver);
+
+	if (watchdog) {
+		watchdog_stop();
+		misc_deregister(&watchdog_miscdev);
+		unregister_reboot_notifier(&watchdog_notifier);
+		release_region(watchdog->sioaddr, 2);
+	}
 }
 
 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-23 23:12           ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API Giel van Schijndel
@ 2010-03-23 23:26             ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:26 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 652 bytes --]

On Wed, Mar 24, 2010 at 12:12:16AM +0100, Giel van Schijndel wrote:
> Implement the watchdog API for the Fintek F71808E.

Looking at the F71889FG datasheet I think implementing watchdog support
for that chip can be accomplished rather easily.

I think it's as simple as adding the pin initialisation (multi function
select registers 0x2a and 0x2b) sequence to the switch statement in
watchdog_start(). That being said; I don't have physical access to that
chip myself, thus I couldn't actually test it (unlike the F71808E, for
which I've already tested these patches).

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-23 23:26             ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-23 23:26 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 652 bytes --]

On Wed, Mar 24, 2010 at 12:12:16AM +0100, Giel van Schijndel wrote:
> Implement the watchdog API for the Fintek F71808E.

Looking at the F71889FG datasheet I think implementing watchdog support
for that chip can be accomplished rather easily.

I think it's as simple as adding the pin initialisation (multi function
select registers 0x2a and 0x2b) sequence to the switch statement in
watchdog_start(). That being said; I don't have physical access to that
chip myself, thus I couldn't actually test it (unlike the F71808E, for
which I've already tested these patches).

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing
  2010-03-23 14:12 ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O regions Giel van Schijndel
@ 2010-03-24  8:14   ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:14 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

I don't have any objections against the proposed changes, but there
are 3 unrelated changes in this patch, please break them up in separate
patches:

1) code cleanup: properly using, previously defined, functions rather
    than duplicating their code.
2) properly acquire I/O regions while probing
3) Make the addresses to probe an array

And IMHO you might just as well drop number 3, it does not really make
the code any better readable, and the old way is how all superio hwmon
drivers do things.

Regards,

Hans


On 03/23/2010 03:12 PM, Giel van Schijndel wrote:
> Acquire the I/O region for the Super I/O chip while we're working on it.
>
> Further alter the way multiple Super I/O addresses are probed for chips
> such that errors in the probing process are passed on from the module
> initialisation function.
>
> Some code cleanup: properly using, previously defined, functions rather
> than duplicating their code.
> ---
>   drivers/hwmon/f71882fg.c |   38 +++++++++++++++++++++++---------------
>   1 files changed, 23 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 4230729..25e1cad 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg)
>   static int superio_inw(int base, int reg)
>   {
>   	int val;
> -	outb(reg++, base);
> -	val = inb(base + 1)<<  8;
> -	outb(reg, base);
> -	val |= inb(base + 1);
> +	val  = superio_inb(base, reg)<<  8;
> +	val |= superio_inb(base, reg + 1);
>   	return val;
>   }
>
> @@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
>   {
>   	u16 val;
>
> -	outb(reg++, data->addr + ADDR_REG_OFFSET);
> -	val = inb(data->addr + DATA_REG_OFFSET)<<  8;
> -	outb(reg, data->addr + ADDR_REG_OFFSET);
> -	val |= inb(data->addr + DATA_REG_OFFSET);
> +	val  = f71882fg_read8(data, reg)<<  8;
> +	val |= f71882fg_read8(data, reg + 1);
>
>   	return val;
>   }
> @@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
>
>   static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
>   {
> -	outb(reg++, data->addr + ADDR_REG_OFFSET);
> -	outb(val>>  8, data->addr + DATA_REG_OFFSET);
> -	outb(reg, data->addr + ADDR_REG_OFFSET);
> -	outb(val&  255, data->addr + DATA_REG_OFFSET);
> +	f71882fg_write8(data, reg,     val>>  8);
> +	f71882fg_write8(data, reg + 1, val&  0xff);
>   }
>
>   static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
> @@ -2184,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   	int err = -ENODEV;
>   	u16 devid;
>
> +	/* Don't step on other driver's I/O space by accident */
> +	if (!request_region(sioaddr, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				(int)sioaddr);
> +		return -EIO;
> +	}
> +
>   	superio_enter(sioaddr);
>
>   	devid = superio_inw(sioaddr, SIO_REG_MANID);
> @@ -2238,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> +	release_region(sioaddr, 2);
>   	return err;
>   }
>
> @@ -2289,14 +2291,20 @@ exit_device_put:
>
>   static int __init f71882fg_init(void)
>   {
> +	static const unsigned short addrs[] = { 0x2e, 0x4e };
>   	int err = -ENODEV;
> -	unsigned short address;
> +	unsigned short address = /* shut up compiler */ 0;
>   	struct f71882fg_sio_data sio_data;
> +	int i;
>
>   	memset(&sio_data, 0, sizeof(sio_data));
>
> -	if (f71882fg_find(0x2e,&address,&sio_data)&&
> -	    f71882fg_find(0x4e,&address,&sio_data))
> +	for (i = 0; i<  ARRAY_SIZE(addrs); i++) {
> +		err = f71882fg_find(addrs[i],&address,&sio_data);
> +		if (err == 0)
> +			break;
> +	}
> +	if (i == ARRAY_SIZE(addrs))
>   		goto exit;
>
>   	err = platform_driver_register(&f71882fg_driver);

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O
@ 2010-03-24  8:14   ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:14 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

I don't have any objections against the proposed changes, but there
are 3 unrelated changes in this patch, please break them up in separate
patches:

1) code cleanup: properly using, previously defined, functions rather
    than duplicating their code.
2) properly acquire I/O regions while probing
3) Make the addresses to probe an array

And IMHO you might just as well drop number 3, it does not really make
the code any better readable, and the old way is how all superio hwmon
drivers do things.

Regards,

Hans


On 03/23/2010 03:12 PM, Giel van Schijndel wrote:
> Acquire the I/O region for the Super I/O chip while we're working on it.
>
> Further alter the way multiple Super I/O addresses are probed for chips
> such that errors in the probing process are passed on from the module
> initialisation function.
>
> Some code cleanup: properly using, previously defined, functions rather
> than duplicating their code.
> ---
>   drivers/hwmon/f71882fg.c |   38 +++++++++++++++++++++++---------------
>   1 files changed, 23 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 4230729..25e1cad 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg)
>   static int superio_inw(int base, int reg)
>   {
>   	int val;
> -	outb(reg++, base);
> -	val = inb(base + 1)<<  8;
> -	outb(reg, base);
> -	val |= inb(base + 1);
> +	val  = superio_inb(base, reg)<<  8;
> +	val |= superio_inb(base, reg + 1);
>   	return val;
>   }
>
> @@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
>   {
>   	u16 val;
>
> -	outb(reg++, data->addr + ADDR_REG_OFFSET);
> -	val = inb(data->addr + DATA_REG_OFFSET)<<  8;
> -	outb(reg, data->addr + ADDR_REG_OFFSET);
> -	val |= inb(data->addr + DATA_REG_OFFSET);
> +	val  = f71882fg_read8(data, reg)<<  8;
> +	val |= f71882fg_read8(data, reg + 1);
>
>   	return val;
>   }
> @@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
>
>   static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
>   {
> -	outb(reg++, data->addr + ADDR_REG_OFFSET);
> -	outb(val>>  8, data->addr + DATA_REG_OFFSET);
> -	outb(reg, data->addr + ADDR_REG_OFFSET);
> -	outb(val&  255, data->addr + DATA_REG_OFFSET);
> +	f71882fg_write8(data, reg,     val>>  8);
> +	f71882fg_write8(data, reg + 1, val&  0xff);
>   }
>
>   static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
> @@ -2184,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   	int err = -ENODEV;
>   	u16 devid;
>
> +	/* Don't step on other driver's I/O space by accident */
> +	if (!request_region(sioaddr, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				(int)sioaddr);
> +		return -EIO;
> +	}
> +
>   	superio_enter(sioaddr);
>
>   	devid = superio_inw(sioaddr, SIO_REG_MANID);
> @@ -2238,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> +	release_region(sioaddr, 2);
>   	return err;
>   }
>
> @@ -2289,14 +2291,20 @@ exit_device_put:
>
>   static int __init f71882fg_init(void)
>   {
> +	static const unsigned short addrs[] = { 0x2e, 0x4e };
>   	int err = -ENODEV;
> -	unsigned short address;
> +	unsigned short address = /* shut up compiler */ 0;
>   	struct f71882fg_sio_data sio_data;
> +	int i;
>
>   	memset(&sio_data, 0, sizeof(sio_data));
>
> -	if (f71882fg_find(0x2e,&address,&sio_data)&&
> -	    f71882fg_find(0x4e,&address,&sio_data))
> +	for (i = 0; i<  ARRAY_SIZE(addrs); i++) {
> +		err = f71882fg_find(addrs[i],&address,&sio_data);
> +		if (err = 0)
> +			break;
> +	}
> +	if (i = ARRAY_SIZE(addrs))
>   		goto exit;
>
>   	err = platform_driver_register(&f71882fg_driver);

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-03-23 23:12     ` [lm-sensors] [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for the Giel van Schijndel
@ 2010-03-24  8:25       ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:25 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

See comments inline.

On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
> Allow device probing to recognise the Fintek F71808E.
>
> Sysfs interface:
>   * Fan/pwm control is the same as for F71889FG
>   * Temperature and voltage sensor handling is largely the same as for
>     the F71889FG
>    - Has one temperature sensor less (doesn't have temp3)
>    - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>      what in7_input refers for F71889FG)
>
> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
> such that it can largely be reused.
> ---
>   Documentation/hwmon/f71882fg |    4 ++
>   drivers/hwmon/Kconfig        |    6 ++--
>   drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>   3 files changed, 79 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
> index a7952c2..1a07fd6 100644
> --- a/Documentation/hwmon/f71882fg
> +++ b/Documentation/hwmon/f71882fg
> @@ -2,6 +2,10 @@ Kernel driver f71882fg
>   ======================
>
>   Supported chips:
> +  * Fintek F71808E
> +    Prefix: 'f71808fg'
> +    Addresses scanned: none, address read from Super I/O config space
> +    Datasheet: Not public
>     * Fintek F71858FG
>       Prefix: 'f71858fg'
>       Addresses scanned: none, address read from Super I/O config space
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index e4595e6..7053608 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -332,11 +332,11 @@ config SENSORS_F71805F
>   	  will be called f71805f.
>
>   config SENSORS_F71882FG
> -	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
> +	tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
>   	depends on EXPERIMENTAL
>   	help
> -	  If you say yes here you get support for hardware monitoring
> -	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
> +	  If you say yes here you get support for hardware monitoring features
> +	  of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
>   	  F71889FG and F8000 Super-I/O chips.
>
>   	  This driver can also be built as a module.  If so, the module
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 25e1cad..b290b87 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -45,6 +45,7 @@
>   #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
>
>   #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
> +#define SIO_F71808_ID		0x0901  /* Chipset ID */
>   #define SIO_F71858_ID		0x0507  /* Chipset ID */
>   #define SIO_F71862_ID		0x0601	/* Chipset ID */
>   #define SIO_F71882_ID		0x0541	/* Chipset ID */
> @@ -96,9 +97,10 @@ static unsigned short force_id;
>   module_param(force_id, ushort, 0);
>   MODULE_PARM_DESC(force_id, "Override the detected device ID");
>
> -enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
> +enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
>
>   static const char *f71882fg_names[] = {
> +	"f71808fg",
>   	"f71858fg",
>   	"f71862fg",
>   	"f71882fg",
> @@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
>   	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
>   };
>
> -/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
> -static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
> +/* In attr common to the f71862fg, f71882fg and f71889fg */
> +static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
>   	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
>   	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
>   	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
> @@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
>   	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
>   	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
>   	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
> +};
> +
> +/* In attr for the f71808fg */
> +static struct sensor_device_attribute_2 f71808_in_attr[] = {
> +	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
> +	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
> +	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
> +	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
> +	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
> +	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
> +	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
> +	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
> +};
> +
> +/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
> +static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
>   	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
>   	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
>   		store_temp_max, 0, 1),
> @@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
>   		store_temp_beep, 0, 6),
>   	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
>   	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
> +};
> +
> +/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
> +static struct sensor_device_attribute_2 f71862_temp_attr[] = {
>   	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
>   	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
>   		store_temp_max, 0, 3),
> @@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
>   				data->temp_type[1] = 6;
>   				break;
>   			}
> +		} else if (data->type == f71808fg) {
> +			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
> +			data->temp_type[1] = (reg&  0x02) ? 2 : 4;
> +			data->temp_type[2] = (reg&  0x04) ? 2 : 4;
> +
>   		} else {
>   			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
>   			if ((reg2&  0x03) == 0x01)
> @@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
>
>   	val /= 1000;
>
> -	if (data->type == f71889fg)
> +	if (data->type == f71889fg
> +	 || data->type == f71808fg)
>   		val = SENSORS_LIMIT(val, -128, 127);
>   	else
>   		val = SENSORS_LIMIT(val, 0, 127);
> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>   			/* fall through! */
>   		case f71862fg:
>   			err = f71882fg_create_sysfs_files(pdev,
> -					fxxxx_in_temp_attr,
> -					ARRAY_SIZE(fxxxx_in_temp_attr));
> +					f71862_temp_attr,
> +					ARRAY_SIZE(f71862_temp_attr));
> +			if (err)
> +				goto exit_unregister_sysfs;
> +			err = f71882fg_create_sysfs_files(pdev,
> +					fxxxx_in_attr,
> +					ARRAY_SIZE(fxxxx_in_attr));
> +			if (err)
> +				goto exit_unregister_sysfs;
> +			/* fall through! */

Ugh, please don't fall through, and then have an if below to only do
some parts of the case falling through. This is quite confusing
at first I thought your code was buggy I had to read it twice to notice
the if. Instead just duplicate the following lines:
 > +			err = f71882fg_create_sysfs_files(pdev,
 > +					fxxxx_temp_attr,
 > +					ARRAY_SIZE(fxxxx_temp_attr));
In the f71862fg case, end the f71862fg case with a break and remove
the if test from the f71808fg case.

> +		case f71808fg:
> +			if (data->type == f71808fg) {
> +				err = f71882fg_create_sysfs_files(pdev,
> +						f71808_in_attr,
> +						ARRAY_SIZE(f71808_in_attr));
> +				if (err)
> +					goto exit_unregister_sysfs;
> +			}
> +			err = f71882fg_create_sysfs_files(pdev,
> +					fxxxx_temp_attr,
> +					ARRAY_SIZE(fxxxx_temp_attr));
>   			break;
>   		case f8000:
>   			err = f71882fg_create_sysfs_files(pdev,
> @@ -2002,6 +2049,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>   		case f71862fg:
>   			err = (data->pwm_enable&  0x15) != 0x15;
>   			break;
> +		case f71808fg:
>   		case f71882fg:
>   		case f71889fg:
>   			err = 0;
> @@ -2047,6 +2095,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>   					f8000_auto_pwm_attr,
>   					ARRAY_SIZE(f8000_auto_pwm_attr));
>   			break;
> +		case f71808fg:
>   		case f71889fg:
>   			for (i = 0; i<  nr_fans; i++) {
>   				data->pwm_auto_point_mapping[i] =
> @@ -2126,8 +2175,20 @@ static int f71882fg_remove(struct platform_device *pdev)
>   			/* fall through! */
>   		case f71862fg:
>   			f71882fg_remove_sysfs_files(pdev,
> -					fxxxx_in_temp_attr,
> -					ARRAY_SIZE(fxxxx_in_temp_attr));
> +					f71862_temp_attr,
> +					ARRAY_SIZE(f71862_temp_attr));
> +			f71882fg_remove_sysfs_files(pdev,
> +					fxxxx_in_attr,
> +					ARRAY_SIZE(fxxxx_in_attr));
> +			/* fall through! */


Idem.

> +		case f71808fg:
> +			if (data->type == f71808fg)
> +				f71882fg_remove_sysfs_files(pdev,
> +						f71808_in_attr,
> +						ARRAY_SIZE(f71808_in_attr));
> +			f71882fg_remove_sysfs_files(pdev,
> +					fxxxx_temp_attr,
> +					ARRAY_SIZE(fxxxx_temp_attr));
>   			break;
>   		case f8000:
>   			f71882fg_remove_sysfs_files(pdev,
> @@ -2195,6 +2256,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>
>   	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
>   	switch (devid) {
> +	case SIO_F71808_ID:
> +		sio_data->type = f71808fg;
> +		break;
>   	case SIO_F71858_ID:
>   		sio_data->type = f71858fg;
>   		break;

Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for
@ 2010-03-24  8:25       ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:25 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

See comments inline.

On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
> Allow device probing to recognise the Fintek F71808E.
>
> Sysfs interface:
>   * Fan/pwm control is the same as for F71889FG
>   * Temperature and voltage sensor handling is largely the same as for
>     the F71889FG
>    - Has one temperature sensor less (doesn't have temp3)
>    - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>      what in7_input refers for F71889FG)
>
> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
> such that it can largely be reused.
> ---
>   Documentation/hwmon/f71882fg |    4 ++
>   drivers/hwmon/Kconfig        |    6 ++--
>   drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>   3 files changed, 79 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
> index a7952c2..1a07fd6 100644
> --- a/Documentation/hwmon/f71882fg
> +++ b/Documentation/hwmon/f71882fg
> @@ -2,6 +2,10 @@ Kernel driver f71882fg
>   ===========
>
>   Supported chips:
> +  * Fintek F71808E
> +    Prefix: 'f71808fg'
> +    Addresses scanned: none, address read from Super I/O config space
> +    Datasheet: Not public
>     * Fintek F71858FG
>       Prefix: 'f71858fg'
>       Addresses scanned: none, address read from Super I/O config space
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index e4595e6..7053608 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -332,11 +332,11 @@ config SENSORS_F71805F
>   	  will be called f71805f.
>
>   config SENSORS_F71882FG
> -	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
> +	tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
>   	depends on EXPERIMENTAL
>   	help
> -	  If you say yes here you get support for hardware monitoring
> -	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
> +	  If you say yes here you get support for hardware monitoring features
> +	  of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
>   	  F71889FG and F8000 Super-I/O chips.
>
>   	  This driver can also be built as a module.  If so, the module
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 25e1cad..b290b87 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -45,6 +45,7 @@
>   #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
>
>   #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
> +#define SIO_F71808_ID		0x0901  /* Chipset ID */
>   #define SIO_F71858_ID		0x0507  /* Chipset ID */
>   #define SIO_F71862_ID		0x0601	/* Chipset ID */
>   #define SIO_F71882_ID		0x0541	/* Chipset ID */
> @@ -96,9 +97,10 @@ static unsigned short force_id;
>   module_param(force_id, ushort, 0);
>   MODULE_PARM_DESC(force_id, "Override the detected device ID");
>
> -enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
> +enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
>
>   static const char *f71882fg_names[] = {
> +	"f71808fg",
>   	"f71858fg",
>   	"f71862fg",
>   	"f71882fg",
> @@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
>   	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
>   };
>
> -/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
> -static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
> +/* In attr common to the f71862fg, f71882fg and f71889fg */
> +static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
>   	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
>   	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
>   	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
> @@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
>   	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
>   	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
>   	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
> +};
> +
> +/* In attr for the f71808fg */
> +static struct sensor_device_attribute_2 f71808_in_attr[] = {
> +	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
> +	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
> +	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
> +	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
> +	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
> +	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
> +	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
> +	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
> +};
> +
> +/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
> +static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
>   	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
>   	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
>   		store_temp_max, 0, 1),
> @@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
>   		store_temp_beep, 0, 6),
>   	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
>   	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
> +};
> +
> +/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
> +static struct sensor_device_attribute_2 f71862_temp_attr[] = {
>   	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
>   	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
>   		store_temp_max, 0, 3),
> @@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
>   				data->temp_type[1] = 6;
>   				break;
>   			}
> +		} else if (data->type = f71808fg) {
> +			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
> +			data->temp_type[1] = (reg&  0x02) ? 2 : 4;
> +			data->temp_type[2] = (reg&  0x04) ? 2 : 4;
> +
>   		} else {
>   			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
>   			if ((reg2&  0x03) = 0x01)
> @@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
>
>   	val /= 1000;
>
> -	if (data->type = f71889fg)
> +	if (data->type = f71889fg
> +	 || data->type = f71808fg)
>   		val = SENSORS_LIMIT(val, -128, 127);
>   	else
>   		val = SENSORS_LIMIT(val, 0, 127);
> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>   			/* fall through! */
>   		case f71862fg:
>   			err = f71882fg_create_sysfs_files(pdev,
> -					fxxxx_in_temp_attr,
> -					ARRAY_SIZE(fxxxx_in_temp_attr));
> +					f71862_temp_attr,
> +					ARRAY_SIZE(f71862_temp_attr));
> +			if (err)
> +				goto exit_unregister_sysfs;
> +			err = f71882fg_create_sysfs_files(pdev,
> +					fxxxx_in_attr,
> +					ARRAY_SIZE(fxxxx_in_attr));
> +			if (err)
> +				goto exit_unregister_sysfs;
> +			/* fall through! */

Ugh, please don't fall through, and then have an if below to only do
some parts of the case falling through. This is quite confusing
at first I thought your code was buggy I had to read it twice to notice
the if. Instead just duplicate the following lines:
 > +			err = f71882fg_create_sysfs_files(pdev,
 > +					fxxxx_temp_attr,
 > +					ARRAY_SIZE(fxxxx_temp_attr));
In the f71862fg case, end the f71862fg case with a break and remove
the if test from the f71808fg case.

> +		case f71808fg:
> +			if (data->type = f71808fg) {
> +				err = f71882fg_create_sysfs_files(pdev,
> +						f71808_in_attr,
> +						ARRAY_SIZE(f71808_in_attr));
> +				if (err)
> +					goto exit_unregister_sysfs;
> +			}
> +			err = f71882fg_create_sysfs_files(pdev,
> +					fxxxx_temp_attr,
> +					ARRAY_SIZE(fxxxx_temp_attr));
>   			break;
>   		case f8000:
>   			err = f71882fg_create_sysfs_files(pdev,
> @@ -2002,6 +2049,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>   		case f71862fg:
>   			err = (data->pwm_enable&  0x15) != 0x15;
>   			break;
> +		case f71808fg:
>   		case f71882fg:
>   		case f71889fg:
>   			err = 0;
> @@ -2047,6 +2095,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>   					f8000_auto_pwm_attr,
>   					ARRAY_SIZE(f8000_auto_pwm_attr));
>   			break;
> +		case f71808fg:
>   		case f71889fg:
>   			for (i = 0; i<  nr_fans; i++) {
>   				data->pwm_auto_point_mapping[i] > @@ -2126,8 +2175,20 @@ static int f71882fg_remove(struct platform_device *pdev)
>   			/* fall through! */
>   		case f71862fg:
>   			f71882fg_remove_sysfs_files(pdev,
> -					fxxxx_in_temp_attr,
> -					ARRAY_SIZE(fxxxx_in_temp_attr));
> +					f71862_temp_attr,
> +					ARRAY_SIZE(f71862_temp_attr));
> +			f71882fg_remove_sysfs_files(pdev,
> +					fxxxx_in_attr,
> +					ARRAY_SIZE(fxxxx_in_attr));
> +			/* fall through! */


Idem.

> +		case f71808fg:
> +			if (data->type = f71808fg)
> +				f71882fg_remove_sysfs_files(pdev,
> +						f71808_in_attr,
> +						ARRAY_SIZE(f71808_in_attr));
> +			f71882fg_remove_sysfs_files(pdev,
> +					fxxxx_temp_attr,
> +					ARRAY_SIZE(fxxxx_temp_attr));
>   			break;
>   		case f8000:
>   			f71882fg_remove_sysfs_files(pdev,
> @@ -2195,6 +2256,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>
>   	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
>   	switch (devid) {
> +	case SIO_F71808_ID:
> +		sio_data->type = f71808fg;
> +		break;
>   	case SIO_F71858_ID:
>   		sio_data->type = f71858fg;
>   		break;

Regards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 2/4] hwmon: f71882fg: prepare for addition of watchdog support
  2010-03-23 23:12       ` [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition of Giel van Schijndel
@ 2010-03-24  8:26         ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:26 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Ack.

Acked-by: Hans de Goede <hdegoede@redhat.com>

On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
> Rename the `address' variable that's used in some places to hwmon_addr
> to indicate it refers to the hardware monitor (HWMON in datasheet)
> "logical device" of the chip.
>
> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |   24 ++++++++++++------------
>   1 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index b290b87..7b31e14 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -2233,7 +2233,7 @@ static int f71882fg_remove(struct platform_device *pdev)
>   	return 0;
>   }
>
> -static int __init f71882fg_find(int sioaddr, unsigned short *address,
> +static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
>   	struct f71882fg_sio_data *sio_data)
>   {
>   	int err = -ENODEV;
> @@ -2290,16 +2290,16 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		goto exit;
>   	}
>
> -	*address = superio_inw(sioaddr, SIO_REG_ADDR);
> -	if (*address == 0) {
> +	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
> +	if (*hwmon_addr == 0) {
>   		printk(KERN_WARNING DRVNAME ": Base address not set\n");
>   		goto exit;
>   	}
> -	*address&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
> +	*hwmon_addr&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
>
>   	err = 0;
>   	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
> -		f71882fg_names[sio_data->type],	(unsigned int)*address,
> +		f71882fg_names[sio_data->type],	(unsigned int)*hwmon_addr,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> @@ -2307,17 +2307,17 @@ exit:
>   	return err;
>   }
>
> -static int __init f71882fg_device_add(unsigned short address,
> +static int __init f71882fg_device_add(unsigned short hwmon_addr,
>   	const struct f71882fg_sio_data *sio_data)
>   {
>   	struct resource res = {
> -		.start	= address,
> -		.end	= address + REGION_LENGTH - 1,
> +		.start	= hwmon_addr,
> +		.end	= hwmon_addr + REGION_LENGTH - 1,
>   		.flags	= IORESOURCE_IO,
>   	};
>   	int err;
>
> -	f71882fg_pdev = platform_device_alloc(DRVNAME, address);
> +	f71882fg_pdev = platform_device_alloc(DRVNAME, hwmon_addr);
>   	if (!f71882fg_pdev)
>   		return -ENOMEM;
>
> @@ -2357,14 +2357,14 @@ static int __init f71882fg_init(void)
>   {
>   	static const unsigned short addrs[] = { 0x2e, 0x4e };
>   	int err = -ENODEV;
> -	unsigned short address = /* shut up compiler */ 0;
> +	unsigned short hwmon_addr = /* shut up compiler */ 0;
>   	struct f71882fg_sio_data sio_data;
>   	int i;
>
>   	memset(&sio_data, 0, sizeof(sio_data));
>
>   	for (i = 0; i<  ARRAY_SIZE(addrs); i++) {
> -		err = f71882fg_find(addrs[i],&address,&sio_data);
> +		err = f71882fg_find(addrs[i],&hwmon_addr,&sio_data);
>   		if (err == 0)
>   			break;
>   	}
> @@ -2375,7 +2375,7 @@ static int __init f71882fg_init(void)
>   	if (err)
>   		goto exit;
>
> -	err = f71882fg_device_add(address,&sio_data);
> +	err = f71882fg_device_add(hwmon_addr,&sio_data);
>   	if (err)
>   		goto exit_driver;
>

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition
@ 2010-03-24  8:26         ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:26 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Ack.

Acked-by: Hans de Goede <hdegoede@redhat.com>

On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
> Rename the `address' variable that's used in some places to hwmon_addr
> to indicate it refers to the hardware monitor (HWMON in datasheet)
> "logical device" of the chip.
>
> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |   24 ++++++++++++------------
>   1 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index b290b87..7b31e14 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -2233,7 +2233,7 @@ static int f71882fg_remove(struct platform_device *pdev)
>   	return 0;
>   }
>
> -static int __init f71882fg_find(int sioaddr, unsigned short *address,
> +static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
>   	struct f71882fg_sio_data *sio_data)
>   {
>   	int err = -ENODEV;
> @@ -2290,16 +2290,16 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		goto exit;
>   	}
>
> -	*address = superio_inw(sioaddr, SIO_REG_ADDR);
> -	if (*address = 0) {
> +	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
> +	if (*hwmon_addr = 0) {
>   		printk(KERN_WARNING DRVNAME ": Base address not set\n");
>   		goto exit;
>   	}
> -	*address&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
> +	*hwmon_addr&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
>
>   	err = 0;
>   	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
> -		f71882fg_names[sio_data->type],	(unsigned int)*address,
> +		f71882fg_names[sio_data->type],	(unsigned int)*hwmon_addr,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> @@ -2307,17 +2307,17 @@ exit:
>   	return err;
>   }
>
> -static int __init f71882fg_device_add(unsigned short address,
> +static int __init f71882fg_device_add(unsigned short hwmon_addr,
>   	const struct f71882fg_sio_data *sio_data)
>   {
>   	struct resource res = {
> -		.start	= address,
> -		.end	= address + REGION_LENGTH - 1,
> +		.start	= hwmon_addr,
> +		.end	= hwmon_addr + REGION_LENGTH - 1,
>   		.flags	= IORESOURCE_IO,
>   	};
>   	int err;
>
> -	f71882fg_pdev = platform_device_alloc(DRVNAME, address);
> +	f71882fg_pdev = platform_device_alloc(DRVNAME, hwmon_addr);
>   	if (!f71882fg_pdev)
>   		return -ENOMEM;
>
> @@ -2357,14 +2357,14 @@ static int __init f71882fg_init(void)
>   {
>   	static const unsigned short addrs[] = { 0x2e, 0x4e };
>   	int err = -ENODEV;
> -	unsigned short address = /* shut up compiler */ 0;
> +	unsigned short hwmon_addr = /* shut up compiler */ 0;
>   	struct f71882fg_sio_data sio_data;
>   	int i;
>
>   	memset(&sio_data, 0, sizeof(sio_data));
>
>   	for (i = 0; i<  ARRAY_SIZE(addrs); i++) {
> -		err = f71882fg_find(addrs[i],&address,&sio_data);
> +		err = f71882fg_find(addrs[i],&hwmon_addr,&sio_data);
>   		if (err = 0)
>   			break;
>   	}
> @@ -2375,7 +2375,7 @@ static int __init f71882fg_init(void)
>   	if (err)
>   		goto exit;
>
> -	err = f71882fg_device_add(address,&sio_data);
> +	err = f71882fg_device_add(hwmon_addr,&sio_data);
>   	if (err)
>   		goto exit_driver;
>

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 2/4] hwmon: f71882fg: prepare for addition of watchdog support
  2010-03-23 23:12       ` [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition of Giel van Schijndel
@ 2010-03-24  8:36         ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:36 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Correction, nack on this one see me reply to patch 4/4

Regards,

Hans


On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
> Rename the `address' variable that's used in some places to hwmon_addr
> to indicate it refers to the hardware monitor (HWMON in datasheet)
> "logical device" of the chip.
>
> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |   24 ++++++++++++------------
>   1 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index b290b87..7b31e14 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -2233,7 +2233,7 @@ static int f71882fg_remove(struct platform_device *pdev)
>   	return 0;
>   }
>
> -static int __init f71882fg_find(int sioaddr, unsigned short *address,
> +static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
>   	struct f71882fg_sio_data *sio_data)
>   {
>   	int err = -ENODEV;
> @@ -2290,16 +2290,16 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		goto exit;
>   	}
>
> -	*address = superio_inw(sioaddr, SIO_REG_ADDR);
> -	if (*address == 0) {
> +	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
> +	if (*hwmon_addr == 0) {
>   		printk(KERN_WARNING DRVNAME ": Base address not set\n");
>   		goto exit;
>   	}
> -	*address&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
> +	*hwmon_addr&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
>
>   	err = 0;
>   	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
> -		f71882fg_names[sio_data->type],	(unsigned int)*address,
> +		f71882fg_names[sio_data->type],	(unsigned int)*hwmon_addr,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> @@ -2307,17 +2307,17 @@ exit:
>   	return err;
>   }
>
> -static int __init f71882fg_device_add(unsigned short address,
> +static int __init f71882fg_device_add(unsigned short hwmon_addr,
>   	const struct f71882fg_sio_data *sio_data)
>   {
>   	struct resource res = {
> -		.start	= address,
> -		.end	= address + REGION_LENGTH - 1,
> +		.start	= hwmon_addr,
> +		.end	= hwmon_addr + REGION_LENGTH - 1,
>   		.flags	= IORESOURCE_IO,
>   	};
>   	int err;
>
> -	f71882fg_pdev = platform_device_alloc(DRVNAME, address);
> +	f71882fg_pdev = platform_device_alloc(DRVNAME, hwmon_addr);
>   	if (!f71882fg_pdev)
>   		return -ENOMEM;
>
> @@ -2357,14 +2357,14 @@ static int __init f71882fg_init(void)
>   {
>   	static const unsigned short addrs[] = { 0x2e, 0x4e };
>   	int err = -ENODEV;
> -	unsigned short address = /* shut up compiler */ 0;
> +	unsigned short hwmon_addr = /* shut up compiler */ 0;
>   	struct f71882fg_sio_data sio_data;
>   	int i;
>
>   	memset(&sio_data, 0, sizeof(sio_data));
>
>   	for (i = 0; i<  ARRAY_SIZE(addrs); i++) {
> -		err = f71882fg_find(addrs[i],&address,&sio_data);
> +		err = f71882fg_find(addrs[i],&hwmon_addr,&sio_data);
>   		if (err == 0)
>   			break;
>   	}
> @@ -2375,7 +2375,7 @@ static int __init f71882fg_init(void)
>   	if (err)
>   		goto exit;
>
> -	err = f71882fg_device_add(address,&sio_data);
> +	err = f71882fg_device_add(hwmon_addr,&sio_data);
>   	if (err)
>   		goto exit_driver;
>

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition
@ 2010-03-24  8:36         ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:36 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Correction, nack on this one see me reply to patch 4/4

Regards,

Hans


On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
> Rename the `address' variable that's used in some places to hwmon_addr
> to indicate it refers to the hardware monitor (HWMON in datasheet)
> "logical device" of the chip.
>
> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |   24 ++++++++++++------------
>   1 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index b290b87..7b31e14 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -2233,7 +2233,7 @@ static int f71882fg_remove(struct platform_device *pdev)
>   	return 0;
>   }
>
> -static int __init f71882fg_find(int sioaddr, unsigned short *address,
> +static int __init f71882fg_find(int sioaddr, unsigned short *hwmon_addr,
>   	struct f71882fg_sio_data *sio_data)
>   {
>   	int err = -ENODEV;
> @@ -2290,16 +2290,16 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		goto exit;
>   	}
>
> -	*address = superio_inw(sioaddr, SIO_REG_ADDR);
> -	if (*address = 0) {
> +	*hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
> +	if (*hwmon_addr = 0) {
>   		printk(KERN_WARNING DRVNAME ": Base address not set\n");
>   		goto exit;
>   	}
> -	*address&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
> +	*hwmon_addr&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
>
>   	err = 0;
>   	printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
> -		f71882fg_names[sio_data->type],	(unsigned int)*address,
> +		f71882fg_names[sio_data->type],	(unsigned int)*hwmon_addr,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> @@ -2307,17 +2307,17 @@ exit:
>   	return err;
>   }
>
> -static int __init f71882fg_device_add(unsigned short address,
> +static int __init f71882fg_device_add(unsigned short hwmon_addr,
>   	const struct f71882fg_sio_data *sio_data)
>   {
>   	struct resource res = {
> -		.start	= address,
> -		.end	= address + REGION_LENGTH - 1,
> +		.start	= hwmon_addr,
> +		.end	= hwmon_addr + REGION_LENGTH - 1,
>   		.flags	= IORESOURCE_IO,
>   	};
>   	int err;
>
> -	f71882fg_pdev = platform_device_alloc(DRVNAME, address);
> +	f71882fg_pdev = platform_device_alloc(DRVNAME, hwmon_addr);
>   	if (!f71882fg_pdev)
>   		return -ENOMEM;
>
> @@ -2357,14 +2357,14 @@ static int __init f71882fg_init(void)
>   {
>   	static const unsigned short addrs[] = { 0x2e, 0x4e };
>   	int err = -ENODEV;
> -	unsigned short address = /* shut up compiler */ 0;
> +	unsigned short hwmon_addr = /* shut up compiler */ 0;
>   	struct f71882fg_sio_data sio_data;
>   	int i;
>
>   	memset(&sio_data, 0, sizeof(sio_data));
>
>   	for (i = 0; i<  ARRAY_SIZE(addrs); i++) {
> -		err = f71882fg_find(addrs[i],&address,&sio_data);
> +		err = f71882fg_find(addrs[i],&hwmon_addr,&sio_data);
>   		if (err = 0)
>   			break;
>   	}
> @@ -2375,7 +2375,7 @@ static int __init f71882fg_init(void)
>   	if (err)
>   		goto exit;
>
> -	err = f71882fg_device_add(address,&sio_data);
> +	err = f71882fg_device_add(hwmon_addr,&sio_data);
>   	if (err)
>   		goto exit_driver;
>

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-23 23:12           ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API Giel van Schijndel
@ 2010-03-24  8:37             ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:37 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

Nack:
As the watchdog has its own SIO logical device number, it should
have a separate driver, not have support glued to the hwmon driver.

Regards,

Hans


On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
> Implement the watchdog API for the Fintek F71808E.
>
> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |  553 ++++++++++++++++++++++++++++++++++++++++++++++
>   1 files changed, 553 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 8006271..3604613 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -26,14 +26,19 @@
>   #include<linux/hwmon.h>
>   #include<linux/hwmon-sysfs.h>
>   #include<linux/err.h>
> +#include<linux/miscdevice.h>
>   #include<linux/mutex.h>
> +#include<linux/notifier.h>
>   #include<linux/io.h>
>   #include<linux/acpi.h>
> +#include<linux/reboot.h>
> +#include<linux/watchdog.h>
>
>   #define DRVNAME "f71882fg"
>
>   #define SIO_F71858FG_LD_HWM	0x02	/* Hardware monitor logical device */
>   #define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device */
> +#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
>   #define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
>   #define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
>
> @@ -91,12 +96,52 @@
>
>   #define	F71882FG_REG_START		0x01
>
> +#define F71808FG_REG_WDO_CONF		0xf0
> +#define F71808FG_REG_WDT_CONF		0xf5
> +#define F71808FG_REG_WD_TIME		0xf6
> +
> +#define F71808FG_FLAG_WDOUT_EN		7
> +
> +#define F71808FG_FLAG_WDTMOUT_STS	5
> +#define F71808FG_FLAG_WD_EN		5
> +#define F71808FG_FLAG_WD_PULSE		4
> +#define F71808FG_FLAG_WD_UNIT		3
> +
>   #define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */
>
> +/* Default values */
> +#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
> +#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
> +#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
> +					   watchdog signal */
> +
>   static unsigned short force_id;
>   module_param(force_id, ushort, 0);
>   MODULE_PARM_DESC(force_id, "Override the detected device ID");
>
> +static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
> +static int timeout = 60;	/* default timeout in seconds */
> +module_param(timeout, int, 0);
> +MODULE_PARM_DESC(timeout,
> +	"Watchdog timeout in seconds. 1<= timeout<="
> +			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
> +			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
> +
> +static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
> +module_param(pulse_width, uint, 0);
> +MODULE_PARM_DESC(pulse_width,
> +	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
> +			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
> +
> +static int nowayout = WATCHDOG_NOWAYOUT;
> +module_param(nowayout, bool, 0444);
> +MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
> +
> +static int start_withtimeout = 0;
> +module_param(start_withtimeout, uint, 0);
> +MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
> +	" given initial timeout. Zero (default) disables this feature.");
> +
>   enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
>
>   static const char *f71882fg_names[] = {
> @@ -113,6 +158,9 @@ static struct platform_device *f71882fg_pdev;
>   /* Super-I/O Function prototypes */
>   static inline int superio_inb(int base, int reg);
>   static inline int superio_inw(int base, int reg);
> +static inline void superio_outb(int base, int reg, u8 val);
> +static inline void superio_set_bit(int base, int reg, int bit);
> +static inline void superio_clear_bit(int base, int reg, int bit);
>   static inline void superio_enter(int base);
>   static inline void superio_select(int base, int ld);
>   static inline void superio_exit(int base);
> @@ -162,6 +210,24 @@ struct f71882fg_data {
>   	s8	pwm_auto_point_temp[4][4];
>   };
>
> +struct watchdog_data {
> +	unsigned short	sioaddr;
> +	enum chips	type;
> +	unsigned long	opened;
> +	struct mutex	lock;
> +	char		expect_close;
> +	struct watchdog_info ident;
> +
> +	unsigned short	timeout;
> +	u8		timer_val;	/* content for the wd_time register */
> +	char		minutes_mode;
> +	u8		pulse_val;	/* pulse width flag */
> +	char		pulse_mode;	/* enable pulse output mode? */
> +	char		caused_reboot;	/* last reboot was by the watchdog */
> +};
> +
> +static struct watchdog_data *watchdog;
> +
>   /* Sysfs in */
>   static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
>   	char *buf);
> @@ -883,6 +949,26 @@ static int superio_inw(int base, int reg)
>   	return val;
>   }
>
> +static inline void superio_outb(int base, int reg, u8 val)
> +{
> +	outb(reg, base);
> +	outb(val, base + 1);
> +}
> +
> +static inline void superio_set_bit(int base, int reg, int bit)
> +{
> +	unsigned long val = superio_inb(base, reg);
> +	__set_bit(bit,&val);
> +	superio_outb(base, reg, val);
> +}
> +
> +static inline void superio_clear_bit(int base, int reg, int bit)
> +{
> +	unsigned long val = superio_inb(base, reg);
> +	__clear_bit(bit,&val);
> +	superio_outb(base, reg, val);
> +}
> +
>   static inline void superio_enter(int base)
>   {
>   	/* according to the datasheet the key must be send twice! */
> @@ -1941,6 +2027,430 @@ static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
>   		device_remove_file(&pdev->dev,&attr[i].dev_attr);
>   }
>
> +static int watchdog_set_timeout(int timeout)
> +{
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	if (timeout<= 0
> +	 || timeout>   max_timeout) {
> +		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&watchdog->lock);
> +
> +	watchdog->timeout = timeout;
> +	if (timeout>  0xff) {
> +		watchdog->timer_val = DIV_ROUND_UP(timeout, 60);
> +		watchdog->minutes_mode = true;
> +	} else {
> +		watchdog->timer_val = timeout;
> +		watchdog->minutes_mode = false;
> +	}
> +
> +	mutex_unlock(&watchdog->lock);
> +
> +	return 0;
> +}
> +
> +static int watchdog_set_pulse_width(unsigned int pw)
> +{
> +	int err = 0;
> +
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	mutex_lock(&watchdog->lock);
> +
> +	if        (pw<=    1) {
> +		watchdog->pulse_val = 0;
> +	} else if (pw<=   25) {
> +		watchdog->pulse_val = 1;
> +	} else if (pw<=  125) {
> +		watchdog->pulse_val = 2;
> +	} else if (pw<= 5000) {
> +		watchdog->pulse_val = 3;
> +	} else {
> +		printk(KERN_ERR DRVNAME ": watchdog pulse width out of range\n");
> +		err = -EINVAL;
> +		goto exit_unlock;
> +	}
> +
> +	watchdog->pulse_mode = pw;
> +
> +exit_unlock:
> +	mutex_unlock(&watchdog->lock);
> +	return err;
> +}
> +
> +static int watchdog_keepalive(void)
> +{
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	mutex_lock(&watchdog->lock);
> +	superio_enter(watchdog->sioaddr);
> +
> +	if (watchdog->minutes_mode)
> +		/* select minutes for timer units */
> +		superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +				F71808FG_FLAG_WD_UNIT);
> +	else
> +		/* select seconds for timer units */
> +		superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +				F71808FG_FLAG_WD_UNIT);
> +
> +	/* Set timer value */
> +	superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
> +			   watchdog->timeout);
> +
> +	superio_exit(watchdog->sioaddr);
> +	mutex_unlock(&watchdog->lock);
> +	return 0;
> +}
> +
> +static int watchdog_start(void)
> +{
> +	/* Make sure we don't die as soon as the watchdog is enabled below */
> +	int err = watchdog_keepalive();
> +	if (err)
> +		return err;
> +
> +	mutex_lock(&watchdog->lock);
> +	superio_enter(watchdog->sioaddr);
> +
> +	/* Watchdog pin configuration */
> +	switch (watchdog->type) {
> +	case f71808fg:
> +		/* Set ping 21 to GPIO23/WDTRST#, then to WDTRST# */
> +		superio_clear_bit(watchdog->sioaddr, 0x2a, 3);
> +		superio_clear_bit(watchdog->sioaddr, 0x2b, 3);
> +		break;
> +
> +	default:
> +		/* 'default' label to shut up the compiler and catch programmer errors */
> +		err = -ENODEV;
> +		goto exit_unlock;
> +	}
> +
> +	superio_select(watchdog->sioaddr, SIO_F71808FG_LD_WDT);
> +	superio_set_bit(watchdog->sioaddr, SIO_REG_ENABLE, 0);
> +	superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDO_CONF,
> +			F71808FG_FLAG_WDOUT_EN);
> +
> +	superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +			F71808FG_FLAG_WD_EN);
> +
> +	if (watchdog->pulse_mode) {
> +		/* Select "pulse" output mode with given duration */
> +		u8 wdt_conf = superio_inb(watchdog->sioaddr,
> +				F71808FG_REG_WDT_CONF);
> +
> +		/* Set WD_PSWIDTH bits (1:0) */
> +		wdt_conf = (wdt_conf&  0xfc) | (watchdog->pulse_val&  0x03);
> +		/* Set WD_PULSE to "pulse" mode */
> +		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
> +
> +		superio_outb(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +				wdt_conf);
> +	} else {
> +		/* Select "level" output mode */
> +		superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +				F71808FG_FLAG_WD_PULSE);
> +	}
> +
> +exit_unlock:
> +	superio_exit(watchdog->sioaddr);
> +	mutex_unlock(&watchdog->lock);
> +
> +	return err;
> +}
> +
> +static int watchdog_stop(void)
> +{
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	mutex_lock(&watchdog->lock);
> +	superio_enter(watchdog->sioaddr);
> +
> +	superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +			F71808FG_FLAG_WD_EN);
> +
> +	superio_exit(watchdog->sioaddr);
> +	mutex_unlock(&watchdog->lock);
> +
> +	return 0;
> +}
> +
> +static int watchdog_get_status(void)
> +{
> +	int status = 0;
> +
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	mutex_lock(&watchdog->lock);
> +	status = (watchdog->caused_reboot) ? WDIOF_CARDRESET : 0;
> +	mutex_unlock(&watchdog->lock);
> +
> +	return status;
> +}
> +
> +/* /dev/watchdog api */
> +
> +static int watchdog_open(struct inode *inode, struct file *file)
> +{
> +	int err;
> +
> +	/* If the watchdog is alive we don't need to start it again */
> +	if (test_and_set_bit(0,&watchdog->opened))
> +		return -EBUSY;
> +
> +	err = watchdog_start();
> +	if (err) {
> +		clear_bit(0,&watchdog->opened);
> +		return err;
> +	}
> +
> +	if (nowayout)
> +		__module_get(THIS_MODULE);
> +
> +	watchdog->expect_close = 0;
> +	return nonseekable_open(inode, file);
> +}
> +
> +static int watchdog_release(struct inode *inode, struct file *file)
> +{
> +	clear_bit(0,&watchdog->opened);
> +
> +	if (!watchdog->expect_close) {
> +		watchdog_keepalive();
> +		printk(KERN_CRIT DRVNAME
> +			": Unexpected close, not stopping watchdog!\n");
> +	} else if (!nowayout) {
> +		watchdog_stop();
> +	}
> +	return 0;
> +}
> +
> +/*
> + *      watchdog_write:
> + *      @file: file handle to the watchdog
> + *      @buf: buffer to write
> + *      @count: count of bytes
> + *      @ppos: pointer to the position to write. No seeks allowed
> + *
> + *      A write to a watchdog device is defined as a keepalive signal. Any
> + *      write of data will do, as we we don't define content meaning.
> + */
> +
> +static ssize_t watchdog_write(struct file *file, const char __user *buf,
> +			    size_t count, loff_t *ppos)
> +{
> +	if (count) {
> +		if (!nowayout) {
> +			size_t i;
> +
> +			/* In case it was set long ago */
> +			bool expect_close = false;
> +
> +			for (i = 0; i != count; i++) {
> +				char c;
> +				if (get_user(c, buf + i))
> +					return -EFAULT;
> +				expect_close = (c == 'V');
> +			}
> +
> +			/* Lock to properly order writes across fork()ed processes */
> +			mutex_lock(&watchdog->lock);
> +			watchdog->expect_close = expect_close;
> +			mutex_unlock(&watchdog->lock);
> +		}
> +
> +		/* someone wrote to us, we should restart timer */
> +		watchdog_keepalive();
> +	}
> +	return count;
> +}
> +
> +/*
> + *      watchdog_ioctl:
> + *      @inode: inode of the device
> + *      @file: file handle to the device
> + *      @cmd: watchdog command
> + *      @arg: argument pointer
> + *
> + *      The watchdog API defines a common set of functions for all watchdogs
> + *      according to their available features.
> + */
> +static long watchdog_ioctl(struct file *file, unsigned int cmd,
> +	unsigned long arg)
> +{
> +	int status;
> +	int new_options;
> +	int new_timeout;
> +	union {
> +		struct watchdog_info __user *ident;
> +		int __user *i;
> +	} uarg;
> +
> +	uarg.i = (int __user *)arg;
> +
> +	switch (cmd) {
> +	case WDIOC_GETSUPPORT:
> +		return copy_to_user(uarg.ident,&watchdog->ident,
> +			sizeof(watchdog->ident)) ? -EFAULT : 0;
> +
> +	case WDIOC_GETSTATUS:
> +		status = watchdog_get_status();
> +		if (status<  0)
> +			return status;
> +		return put_user(status, uarg.i);
> +
> +	case WDIOC_GETBOOTSTATUS:
> +		return put_user(0, uarg.i);
> +
> +	case WDIOC_SETOPTIONS:
> +		if (get_user(new_options, uarg.i))
> +			return -EFAULT;
> +
> +		if (new_options&  WDIOS_DISABLECARD) {
> +			watchdog_stop();
> +		}
> +
> +		if (new_options&  WDIOS_ENABLECARD)
> +			return watchdog_start();
> +
> +
> +	case WDIOC_KEEPALIVE:
> +		watchdog_keepalive();
> +		return 0;
> +
> +	case WDIOC_SETTIMEOUT:
> +		if (get_user(new_timeout, uarg.i))
> +			return -EFAULT;
> +
> +		if (watchdog_set_timeout(new_timeout))
> +			return -EINVAL;
> +
> +		watchdog_keepalive();
> +		/* Fall */
> +
> +	case WDIOC_GETTIMEOUT:
> +		return put_user(watchdog->timeout, uarg.i);
> +
> +	default:
> +		return -ENOTTY;
> +
> +	}
> +}
> +
> +static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
> +	void *unused)
> +{
> +	if (code == SYS_DOWN || code == SYS_HALT)
> +		watchdog_stop();
> +	return NOTIFY_DONE;
> +}
> +
> +static const struct file_operations watchdog_fops = {
> +	.owner		= THIS_MODULE,
> +	.llseek		= no_llseek,
> +	.open		= watchdog_open,
> +	.release	= watchdog_release,
> +	.write		= watchdog_write,
> +	.unlocked_ioctl	= watchdog_ioctl,
> +};
> +
> +static struct miscdevice watchdog_miscdev = {
> +	.minor		= WATCHDOG_MINOR,
> +	.name		= "watchdog",
> +	.fops		=&watchdog_fops,
> +};
> +
> +static struct notifier_block watchdog_notifier = {
> +	.notifier_call = watchdog_notify_sys,
> +};
> +
> +static int __init watchdog_init(void)
> +{
> +	int err = 0;
> +
> +	if (!request_region(watchdog->sioaddr, 2,
> +			watchdog->ident.identity)) {
> +		printk(KERN_ERR DRVNAME
> +			": I/O address 0x%04x already in use\n",
> +				(int)watchdog->sioaddr);
> +		return -EIO;
> +	}
> +
> +	err = register_reboot_notifier(&watchdog_notifier);
> +	if (err)
> +		goto exit_region;
> +
> +	err = misc_register(&watchdog_miscdev);
> +	if (err) {
> +		printk(KERN_ERR DRVNAME
> +			": cannot register miscdev on minor=%d\n",
> +				watchdog_miscdev.minor);
> +		goto exit_reboot;
> +	}
> +
> +	if (start_withtimeout) {
> +		if (start_withtimeout<= 0
> +		 || start_withtimeout>   max_timeout) {
> +			printk(KERN_ERR DRVNAME ": watchdog starting timeout out of range\n");
> +			err = -EINVAL;
> +			goto exit_reboot;
> +		}
> +
> +		err = watchdog_start();
> +		if (err) {
> +			printk(KERN_ERR DRVNAME
> +				": cannot start watchdog timer\n");
> +			goto exit_reboot;
> +		}
> +
> +		mutex_lock(&watchdog->lock);
> +		superio_enter(watchdog->sioaddr);
> +
> +		if (start_withtimeout>  0xff) {
> +			/* select minutes for timer units */
> +			superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +					F71808FG_FLAG_WD_UNIT);
> +			superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
> +					   DIV_ROUND_UP(start_withtimeout, 60));
> +		} else {
> +			/* select seconds for timer units */
> +			superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +					F71808FG_FLAG_WD_UNIT);
> +			superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
> +					   start_withtimeout);
> +		}
> +
> +		superio_exit(watchdog->sioaddr);
> +		mutex_unlock(&watchdog->lock);
> +
> +		if (nowayout)
> +			__module_get(THIS_MODULE);
> +
> +		printk(KERN_INFO DRVNAME
> +			": watchdog started with initial timeout of %d seconds!\n",
> +			start_withtimeout);
> +	}
> +
> +	return 0;
> +
> +exit_reboot:
> +	unregister_reboot_notifier(&watchdog_notifier);
> +exit_region:
> +	release_region(watchdog->sioaddr, 2);
> +
> +	return err;
> +}
> +
>   static int __devinit f71882fg_probe(struct platform_device *pdev)
>   {
>   	struct f71882fg_data *data;
> @@ -2236,8 +2746,32 @@ static int f71882fg_remove(struct platform_device *pdev)
>   static int __init f71882fg_find_watchdog(int sioaddr,
>   	const struct f71882fg_sio_data *sio_data)
>   {
> +	int err = 0;
> +
>   	switch (sio_data->type) {
>   	case f71808fg:
> +		watchdog = kzalloc(sizeof(*watchdog), GFP_KERNEL);
> +		if (!watchdog)
> +			return -ENOMEM;
> +
> +		mutex_init(&watchdog->lock);
> +		watchdog->sioaddr = sioaddr;
> +		watchdog->type = sio_data->type;
> +
> +		watchdog->ident.options = WDIOC_SETTIMEOUT
> +					| WDIOF_MAGICCLOSE
> +					| WDIOF_KEEPALIVEPING;
> +		snprintf(watchdog->ident.identity,
> +			sizeof(watchdog->ident.identity), "%s watchdog",
> +			f71882fg_names[watchdog->type]);
> +
> +		err = watchdog_set_timeout(timeout);
> +		if (err)
> +			goto exit_alloc;
> +		err = watchdog_set_pulse_width(pulse_width);
> +		if (err)
> +			goto exit_alloc;
> +
>   		break;
>
>   	case f71862fg:
> @@ -2256,6 +2790,12 @@ static int __init f71882fg_find_watchdog(int sioaddr,
>   	}
>
>   	return 0;
> +
> +exit_alloc:
> +	kfree(watchdog);
> +	watchdog = NULL;
> +
> +	return err;
>   }
>
>   static int __init f71882fg_find_hwmon(int sioaddr, unsigned short *hwmon_addr,
> @@ -2421,6 +2961,12 @@ static int __init f71882fg_init(void)
>   	if (err)
>   		goto exit_driver;
>
> +	if (watchdog) {
> +		err = watchdog_init();
> +		if (err)
> +			goto exit_driver;
> +	}
> +
>   	return 0;
>
>   exit_driver:
> @@ -2433,6 +2979,13 @@ static void __exit f71882fg_exit(void)
>   {
>   	platform_device_unregister(f71882fg_pdev);
>   	platform_driver_unregister(&f71882fg_driver);
> +
> +	if (watchdog) {
> +		watchdog_stop();
> +		misc_deregister(&watchdog_miscdev);
> +		unregister_reboot_notifier(&watchdog_notifier);
> +		release_region(watchdog->sioaddr, 2);
> +	}
>   }
>
>   MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-24  8:37             ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24  8:37 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

Nack:
As the watchdog has its own SIO logical device number, it should
have a separate driver, not have support glued to the hwmon driver.

Regards,

Hans


On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
> Implement the watchdog API for the Fintek F71808E.
>
> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |  553 ++++++++++++++++++++++++++++++++++++++++++++++
>   1 files changed, 553 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 8006271..3604613 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -26,14 +26,19 @@
>   #include<linux/hwmon.h>
>   #include<linux/hwmon-sysfs.h>
>   #include<linux/err.h>
> +#include<linux/miscdevice.h>
>   #include<linux/mutex.h>
> +#include<linux/notifier.h>
>   #include<linux/io.h>
>   #include<linux/acpi.h>
> +#include<linux/reboot.h>
> +#include<linux/watchdog.h>
>
>   #define DRVNAME "f71882fg"
>
>   #define SIO_F71858FG_LD_HWM	0x02	/* Hardware monitor logical device */
>   #define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device */
> +#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
>   #define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
>   #define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
>
> @@ -91,12 +96,52 @@
>
>   #define	F71882FG_REG_START		0x01
>
> +#define F71808FG_REG_WDO_CONF		0xf0
> +#define F71808FG_REG_WDT_CONF		0xf5
> +#define F71808FG_REG_WD_TIME		0xf6
> +
> +#define F71808FG_FLAG_WDOUT_EN		7
> +
> +#define F71808FG_FLAG_WDTMOUT_STS	5
> +#define F71808FG_FLAG_WD_EN		5
> +#define F71808FG_FLAG_WD_PULSE		4
> +#define F71808FG_FLAG_WD_UNIT		3
> +
>   #define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */
>
> +/* Default values */
> +#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
> +#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
> +#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
> +					   watchdog signal */
> +
>   static unsigned short force_id;
>   module_param(force_id, ushort, 0);
>   MODULE_PARM_DESC(force_id, "Override the detected device ID");
>
> +static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
> +static int timeout = 60;	/* default timeout in seconds */
> +module_param(timeout, int, 0);
> +MODULE_PARM_DESC(timeout,
> +	"Watchdog timeout in seconds. 1<= timeout<="
> +			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
> +			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
> +
> +static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
> +module_param(pulse_width, uint, 0);
> +MODULE_PARM_DESC(pulse_width,
> +	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
> +			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
> +
> +static int nowayout = WATCHDOG_NOWAYOUT;
> +module_param(nowayout, bool, 0444);
> +MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
> +
> +static int start_withtimeout = 0;
> +module_param(start_withtimeout, uint, 0);
> +MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
> +	" given initial timeout. Zero (default) disables this feature.");
> +
>   enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
>
>   static const char *f71882fg_names[] = {
> @@ -113,6 +158,9 @@ static struct platform_device *f71882fg_pdev;
>   /* Super-I/O Function prototypes */
>   static inline int superio_inb(int base, int reg);
>   static inline int superio_inw(int base, int reg);
> +static inline void superio_outb(int base, int reg, u8 val);
> +static inline void superio_set_bit(int base, int reg, int bit);
> +static inline void superio_clear_bit(int base, int reg, int bit);
>   static inline void superio_enter(int base);
>   static inline void superio_select(int base, int ld);
>   static inline void superio_exit(int base);
> @@ -162,6 +210,24 @@ struct f71882fg_data {
>   	s8	pwm_auto_point_temp[4][4];
>   };
>
> +struct watchdog_data {
> +	unsigned short	sioaddr;
> +	enum chips	type;
> +	unsigned long	opened;
> +	struct mutex	lock;
> +	char		expect_close;
> +	struct watchdog_info ident;
> +
> +	unsigned short	timeout;
> +	u8		timer_val;	/* content for the wd_time register */
> +	char		minutes_mode;
> +	u8		pulse_val;	/* pulse width flag */
> +	char		pulse_mode;	/* enable pulse output mode? */
> +	char		caused_reboot;	/* last reboot was by the watchdog */
> +};
> +
> +static struct watchdog_data *watchdog;
> +
>   /* Sysfs in */
>   static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
>   	char *buf);
> @@ -883,6 +949,26 @@ static int superio_inw(int base, int reg)
>   	return val;
>   }
>
> +static inline void superio_outb(int base, int reg, u8 val)
> +{
> +	outb(reg, base);
> +	outb(val, base + 1);
> +}
> +
> +static inline void superio_set_bit(int base, int reg, int bit)
> +{
> +	unsigned long val = superio_inb(base, reg);
> +	__set_bit(bit,&val);
> +	superio_outb(base, reg, val);
> +}
> +
> +static inline void superio_clear_bit(int base, int reg, int bit)
> +{
> +	unsigned long val = superio_inb(base, reg);
> +	__clear_bit(bit,&val);
> +	superio_outb(base, reg, val);
> +}
> +
>   static inline void superio_enter(int base)
>   {
>   	/* according to the datasheet the key must be send twice! */
> @@ -1941,6 +2027,430 @@ static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
>   		device_remove_file(&pdev->dev,&attr[i].dev_attr);
>   }
>
> +static int watchdog_set_timeout(int timeout)
> +{
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	if (timeout<= 0
> +	 || timeout>   max_timeout) {
> +		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&watchdog->lock);
> +
> +	watchdog->timeout = timeout;
> +	if (timeout>  0xff) {
> +		watchdog->timer_val = DIV_ROUND_UP(timeout, 60);
> +		watchdog->minutes_mode = true;
> +	} else {
> +		watchdog->timer_val = timeout;
> +		watchdog->minutes_mode = false;
> +	}
> +
> +	mutex_unlock(&watchdog->lock);
> +
> +	return 0;
> +}
> +
> +static int watchdog_set_pulse_width(unsigned int pw)
> +{
> +	int err = 0;
> +
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	mutex_lock(&watchdog->lock);
> +
> +	if        (pw<=    1) {
> +		watchdog->pulse_val = 0;
> +	} else if (pw<=   25) {
> +		watchdog->pulse_val = 1;
> +	} else if (pw<=  125) {
> +		watchdog->pulse_val = 2;
> +	} else if (pw<= 5000) {
> +		watchdog->pulse_val = 3;
> +	} else {
> +		printk(KERN_ERR DRVNAME ": watchdog pulse width out of range\n");
> +		err = -EINVAL;
> +		goto exit_unlock;
> +	}
> +
> +	watchdog->pulse_mode = pw;
> +
> +exit_unlock:
> +	mutex_unlock(&watchdog->lock);
> +	return err;
> +}
> +
> +static int watchdog_keepalive(void)
> +{
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	mutex_lock(&watchdog->lock);
> +	superio_enter(watchdog->sioaddr);
> +
> +	if (watchdog->minutes_mode)
> +		/* select minutes for timer units */
> +		superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +				F71808FG_FLAG_WD_UNIT);
> +	else
> +		/* select seconds for timer units */
> +		superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +				F71808FG_FLAG_WD_UNIT);
> +
> +	/* Set timer value */
> +	superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
> +			   watchdog->timeout);
> +
> +	superio_exit(watchdog->sioaddr);
> +	mutex_unlock(&watchdog->lock);
> +	return 0;
> +}
> +
> +static int watchdog_start(void)
> +{
> +	/* Make sure we don't die as soon as the watchdog is enabled below */
> +	int err = watchdog_keepalive();
> +	if (err)
> +		return err;
> +
> +	mutex_lock(&watchdog->lock);
> +	superio_enter(watchdog->sioaddr);
> +
> +	/* Watchdog pin configuration */
> +	switch (watchdog->type) {
> +	case f71808fg:
> +		/* Set ping 21 to GPIO23/WDTRST#, then to WDTRST# */
> +		superio_clear_bit(watchdog->sioaddr, 0x2a, 3);
> +		superio_clear_bit(watchdog->sioaddr, 0x2b, 3);
> +		break;
> +
> +	default:
> +		/* 'default' label to shut up the compiler and catch programmer errors */
> +		err = -ENODEV;
> +		goto exit_unlock;
> +	}
> +
> +	superio_select(watchdog->sioaddr, SIO_F71808FG_LD_WDT);
> +	superio_set_bit(watchdog->sioaddr, SIO_REG_ENABLE, 0);
> +	superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDO_CONF,
> +			F71808FG_FLAG_WDOUT_EN);
> +
> +	superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +			F71808FG_FLAG_WD_EN);
> +
> +	if (watchdog->pulse_mode) {
> +		/* Select "pulse" output mode with given duration */
> +		u8 wdt_conf = superio_inb(watchdog->sioaddr,
> +				F71808FG_REG_WDT_CONF);
> +
> +		/* Set WD_PSWIDTH bits (1:0) */
> +		wdt_conf = (wdt_conf&  0xfc) | (watchdog->pulse_val&  0x03);
> +		/* Set WD_PULSE to "pulse" mode */
> +		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
> +
> +		superio_outb(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +				wdt_conf);
> +	} else {
> +		/* Select "level" output mode */
> +		superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +				F71808FG_FLAG_WD_PULSE);
> +	}
> +
> +exit_unlock:
> +	superio_exit(watchdog->sioaddr);
> +	mutex_unlock(&watchdog->lock);
> +
> +	return err;
> +}
> +
> +static int watchdog_stop(void)
> +{
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	mutex_lock(&watchdog->lock);
> +	superio_enter(watchdog->sioaddr);
> +
> +	superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +			F71808FG_FLAG_WD_EN);
> +
> +	superio_exit(watchdog->sioaddr);
> +	mutex_unlock(&watchdog->lock);
> +
> +	return 0;
> +}
> +
> +static int watchdog_get_status(void)
> +{
> +	int status = 0;
> +
> +	if (!watchdog)
> +		return -ENODEV;
> +
> +	mutex_lock(&watchdog->lock);
> +	status = (watchdog->caused_reboot) ? WDIOF_CARDRESET : 0;
> +	mutex_unlock(&watchdog->lock);
> +
> +	return status;
> +}
> +
> +/* /dev/watchdog api */
> +
> +static int watchdog_open(struct inode *inode, struct file *file)
> +{
> +	int err;
> +
> +	/* If the watchdog is alive we don't need to start it again */
> +	if (test_and_set_bit(0,&watchdog->opened))
> +		return -EBUSY;
> +
> +	err = watchdog_start();
> +	if (err) {
> +		clear_bit(0,&watchdog->opened);
> +		return err;
> +	}
> +
> +	if (nowayout)
> +		__module_get(THIS_MODULE);
> +
> +	watchdog->expect_close = 0;
> +	return nonseekable_open(inode, file);
> +}
> +
> +static int watchdog_release(struct inode *inode, struct file *file)
> +{
> +	clear_bit(0,&watchdog->opened);
> +
> +	if (!watchdog->expect_close) {
> +		watchdog_keepalive();
> +		printk(KERN_CRIT DRVNAME
> +			": Unexpected close, not stopping watchdog!\n");
> +	} else if (!nowayout) {
> +		watchdog_stop();
> +	}
> +	return 0;
> +}
> +
> +/*
> + *      watchdog_write:
> + *      @file: file handle to the watchdog
> + *      @buf: buffer to write
> + *      @count: count of bytes
> + *      @ppos: pointer to the position to write. No seeks allowed
> + *
> + *      A write to a watchdog device is defined as a keepalive signal. Any
> + *      write of data will do, as we we don't define content meaning.
> + */
> +
> +static ssize_t watchdog_write(struct file *file, const char __user *buf,
> +			    size_t count, loff_t *ppos)
> +{
> +	if (count) {
> +		if (!nowayout) {
> +			size_t i;
> +
> +			/* In case it was set long ago */
> +			bool expect_close = false;
> +
> +			for (i = 0; i != count; i++) {
> +				char c;
> +				if (get_user(c, buf + i))
> +					return -EFAULT;
> +				expect_close = (c = 'V');
> +			}
> +
> +			/* Lock to properly order writes across fork()ed processes */
> +			mutex_lock(&watchdog->lock);
> +			watchdog->expect_close = expect_close;
> +			mutex_unlock(&watchdog->lock);
> +		}
> +
> +		/* someone wrote to us, we should restart timer */
> +		watchdog_keepalive();
> +	}
> +	return count;
> +}
> +
> +/*
> + *      watchdog_ioctl:
> + *      @inode: inode of the device
> + *      @file: file handle to the device
> + *      @cmd: watchdog command
> + *      @arg: argument pointer
> + *
> + *      The watchdog API defines a common set of functions for all watchdogs
> + *      according to their available features.
> + */
> +static long watchdog_ioctl(struct file *file, unsigned int cmd,
> +	unsigned long arg)
> +{
> +	int status;
> +	int new_options;
> +	int new_timeout;
> +	union {
> +		struct watchdog_info __user *ident;
> +		int __user *i;
> +	} uarg;
> +
> +	uarg.i = (int __user *)arg;
> +
> +	switch (cmd) {
> +	case WDIOC_GETSUPPORT:
> +		return copy_to_user(uarg.ident,&watchdog->ident,
> +			sizeof(watchdog->ident)) ? -EFAULT : 0;
> +
> +	case WDIOC_GETSTATUS:
> +		status = watchdog_get_status();
> +		if (status<  0)
> +			return status;
> +		return put_user(status, uarg.i);
> +
> +	case WDIOC_GETBOOTSTATUS:
> +		return put_user(0, uarg.i);
> +
> +	case WDIOC_SETOPTIONS:
> +		if (get_user(new_options, uarg.i))
> +			return -EFAULT;
> +
> +		if (new_options&  WDIOS_DISABLECARD) {
> +			watchdog_stop();
> +		}
> +
> +		if (new_options&  WDIOS_ENABLECARD)
> +			return watchdog_start();
> +
> +
> +	case WDIOC_KEEPALIVE:
> +		watchdog_keepalive();
> +		return 0;
> +
> +	case WDIOC_SETTIMEOUT:
> +		if (get_user(new_timeout, uarg.i))
> +			return -EFAULT;
> +
> +		if (watchdog_set_timeout(new_timeout))
> +			return -EINVAL;
> +
> +		watchdog_keepalive();
> +		/* Fall */
> +
> +	case WDIOC_GETTIMEOUT:
> +		return put_user(watchdog->timeout, uarg.i);
> +
> +	default:
> +		return -ENOTTY;
> +
> +	}
> +}
> +
> +static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
> +	void *unused)
> +{
> +	if (code = SYS_DOWN || code = SYS_HALT)
> +		watchdog_stop();
> +	return NOTIFY_DONE;
> +}
> +
> +static const struct file_operations watchdog_fops = {
> +	.owner		= THIS_MODULE,
> +	.llseek		= no_llseek,
> +	.open		= watchdog_open,
> +	.release	= watchdog_release,
> +	.write		= watchdog_write,
> +	.unlocked_ioctl	= watchdog_ioctl,
> +};
> +
> +static struct miscdevice watchdog_miscdev = {
> +	.minor		= WATCHDOG_MINOR,
> +	.name		= "watchdog",
> +	.fops		=&watchdog_fops,
> +};
> +
> +static struct notifier_block watchdog_notifier = {
> +	.notifier_call = watchdog_notify_sys,
> +};
> +
> +static int __init watchdog_init(void)
> +{
> +	int err = 0;
> +
> +	if (!request_region(watchdog->sioaddr, 2,
> +			watchdog->ident.identity)) {
> +		printk(KERN_ERR DRVNAME
> +			": I/O address 0x%04x already in use\n",
> +				(int)watchdog->sioaddr);
> +		return -EIO;
> +	}
> +
> +	err = register_reboot_notifier(&watchdog_notifier);
> +	if (err)
> +		goto exit_region;
> +
> +	err = misc_register(&watchdog_miscdev);
> +	if (err) {
> +		printk(KERN_ERR DRVNAME
> +			": cannot register miscdev on minor=%d\n",
> +				watchdog_miscdev.minor);
> +		goto exit_reboot;
> +	}
> +
> +	if (start_withtimeout) {
> +		if (start_withtimeout<= 0
> +		 || start_withtimeout>   max_timeout) {
> +			printk(KERN_ERR DRVNAME ": watchdog starting timeout out of range\n");
> +			err = -EINVAL;
> +			goto exit_reboot;
> +		}
> +
> +		err = watchdog_start();
> +		if (err) {
> +			printk(KERN_ERR DRVNAME
> +				": cannot start watchdog timer\n");
> +			goto exit_reboot;
> +		}
> +
> +		mutex_lock(&watchdog->lock);
> +		superio_enter(watchdog->sioaddr);
> +
> +		if (start_withtimeout>  0xff) {
> +			/* select minutes for timer units */
> +			superio_set_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +					F71808FG_FLAG_WD_UNIT);
> +			superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
> +					   DIV_ROUND_UP(start_withtimeout, 60));
> +		} else {
> +			/* select seconds for timer units */
> +			superio_clear_bit(watchdog->sioaddr, F71808FG_REG_WDT_CONF,
> +					F71808FG_FLAG_WD_UNIT);
> +			superio_outb(watchdog->sioaddr, F71808FG_REG_WD_TIME,
> +					   start_withtimeout);
> +		}
> +
> +		superio_exit(watchdog->sioaddr);
> +		mutex_unlock(&watchdog->lock);
> +
> +		if (nowayout)
> +			__module_get(THIS_MODULE);
> +
> +		printk(KERN_INFO DRVNAME
> +			": watchdog started with initial timeout of %d seconds!\n",
> +			start_withtimeout);
> +	}
> +
> +	return 0;
> +
> +exit_reboot:
> +	unregister_reboot_notifier(&watchdog_notifier);
> +exit_region:
> +	release_region(watchdog->sioaddr, 2);
> +
> +	return err;
> +}
> +
>   static int __devinit f71882fg_probe(struct platform_device *pdev)
>   {
>   	struct f71882fg_data *data;
> @@ -2236,8 +2746,32 @@ static int f71882fg_remove(struct platform_device *pdev)
>   static int __init f71882fg_find_watchdog(int sioaddr,
>   	const struct f71882fg_sio_data *sio_data)
>   {
> +	int err = 0;
> +
>   	switch (sio_data->type) {
>   	case f71808fg:
> +		watchdog = kzalloc(sizeof(*watchdog), GFP_KERNEL);
> +		if (!watchdog)
> +			return -ENOMEM;
> +
> +		mutex_init(&watchdog->lock);
> +		watchdog->sioaddr = sioaddr;
> +		watchdog->type = sio_data->type;
> +
> +		watchdog->ident.options = WDIOC_SETTIMEOUT
> +					| WDIOF_MAGICCLOSE
> +					| WDIOF_KEEPALIVEPING;
> +		snprintf(watchdog->ident.identity,
> +			sizeof(watchdog->ident.identity), "%s watchdog",
> +			f71882fg_names[watchdog->type]);
> +
> +		err = watchdog_set_timeout(timeout);
> +		if (err)
> +			goto exit_alloc;
> +		err = watchdog_set_pulse_width(pulse_width);
> +		if (err)
> +			goto exit_alloc;
> +
>   		break;
>
>   	case f71862fg:
> @@ -2256,6 +2790,12 @@ static int __init f71882fg_find_watchdog(int sioaddr,
>   	}
>
>   	return 0;
> +
> +exit_alloc:
> +	kfree(watchdog);
> +	watchdog = NULL;
> +
> +	return err;
>   }
>
>   static int __init f71882fg_find_hwmon(int sioaddr, unsigned short *hwmon_addr,
> @@ -2421,6 +2961,12 @@ static int __init f71882fg_init(void)
>   	if (err)
>   		goto exit_driver;
>
> +	if (watchdog) {
> +		err = watchdog_init();
> +		if (err)
> +			goto exit_driver;
> +	}
> +
>   	return 0;
>
>   exit_driver:
> @@ -2433,6 +2979,13 @@ static void __exit f71882fg_exit(void)
>   {
>   	platform_device_unregister(f71882fg_pdev);
>   	platform_driver_unregister(&f71882fg_driver);
> +
> +	if (watchdog) {
> +		watchdog_stop();
> +		misc_deregister(&watchdog_miscdev);
> +		unregister_reboot_notifier(&watchdog_notifier);
> +		release_region(watchdog->sioaddr, 2);
> +	}
>   }
>
>   MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing
  2010-03-24  8:14   ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Hans de Goede
@ 2010-03-24  8:46     ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  8:46 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2336 bytes --]

On Wed, Mar 24, 2010 at 09:14:14AM +0100, Hans de Goede wrote:
> I don't have any objections against the proposed changes, but there
> are 3 unrelated changes in this patch, please break them up in
> separate patches:
> 
> 1) code cleanup: properly using, previously defined, functions rather
>    than duplicating their code.
> 2) properly acquire I/O regions while probing
> 3) Make the addresses to probe an array
> 
> And IMHO you might just as well drop number 3, it does not really make
> the code any better readable, and the old way is how all superio hwmon
> drivers do things.

Okay, broken up patches will follow as replies to this message.

Regarding number (3), my goal wasn't to put the probe addresses in an
array. My goal (as I think should have been made clear by the commit
message I had added) was to make sure that upon failure f71882fg_find's
return value gets passed back from the module's init function. This to
make sure the *proper* error code gets passed back to the user of
insmod/modprobe (as opposed to it being replaced by -ENODEV).

Further I think non -ENODEV errors should probably immediately result in
module initialisation failing (rather than retrying a probe), that's a
design choice though (which my patch doesn't bother addressing right
now).

However, regarding the for-loop/array thing, the same behaviour can be
aqcuired with a patch like the one following this line. (Please tell me
if you like this approach or something similar better. Though,
personally, I think it's "hackisher"/dirtier).

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4230729..42d6304 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2295,9 +2295,11 @@ static int __init f71882fg_init(void)
 
        memset(&sio_data, 0, sizeof(sio_data));
 
-       if (f71882fg_find(0x2e, &address, &sio_data) &&
-           f71882fg_find(0x4e, &address, &sio_data))
-               goto exit;
+       if (f71882fg_find(0x2e, &address, &sio_data)) {
+               err = f71882fg_find(0x4e, &address, &sio_data);
+               if (err)
+                       goto exit;
+       }
 
        err = platform_driver_register(&f71882fg_driver);
        if (err)

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O
@ 2010-03-24  8:46     ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  8:46 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2336 bytes --]

On Wed, Mar 24, 2010 at 09:14:14AM +0100, Hans de Goede wrote:
> I don't have any objections against the proposed changes, but there
> are 3 unrelated changes in this patch, please break them up in
> separate patches:
> 
> 1) code cleanup: properly using, previously defined, functions rather
>    than duplicating their code.
> 2) properly acquire I/O regions while probing
> 3) Make the addresses to probe an array
> 
> And IMHO you might just as well drop number 3, it does not really make
> the code any better readable, and the old way is how all superio hwmon
> drivers do things.

Okay, broken up patches will follow as replies to this message.

Regarding number (3), my goal wasn't to put the probe addresses in an
array. My goal (as I think should have been made clear by the commit
message I had added) was to make sure that upon failure f71882fg_find's
return value gets passed back from the module's init function. This to
make sure the *proper* error code gets passed back to the user of
insmod/modprobe (as opposed to it being replaced by -ENODEV).

Further I think non -ENODEV errors should probably immediately result in
module initialisation failing (rather than retrying a probe), that's a
design choice though (which my patch doesn't bother addressing right
now).

However, regarding the for-loop/array thing, the same behaviour can be
aqcuired with a patch like the one following this line. (Please tell me
if you like this approach or something similar better. Though,
personally, I think it's "hackisher"/dirtier).

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4230729..42d6304 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2295,9 +2295,11 @@ static int __init f71882fg_init(void)
 
        memset(&sio_data, 0, sizeof(sio_data));
 
-       if (f71882fg_find(0x2e, &address, &sio_data) &&
-           f71882fg_find(0x4e, &address, &sio_data))
-               goto exit;
+       if (f71882fg_find(0x2e, &address, &sio_data)) {
+               err = f71882fg_find(0x4e, &address, &sio_data);
+               if (err)
+                       goto exit;
+       }
 
        err = platform_driver_register(&f71882fg_driver);
        if (err)

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH] hwmon: f71882fg: code cleanup
  2010-03-24  8:46     ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
@ 2010-03-24  9:09       ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Some code cleanup: properly using previously defined functions, rather
than duplicating their code.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   18 ++++++------------
 1 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4230729..ca34e5c 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg)
 static int superio_inw(int base, int reg)
 {
 	int val;
-	outb(reg++, base);
-	val = inb(base + 1) << 8;
-	outb(reg, base);
-	val |= inb(base + 1);
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
 	return val;
 }
 
@@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
 {
 	u16 val;
 
-	outb(reg++, data->addr + ADDR_REG_OFFSET);
-	val = inb(data->addr + DATA_REG_OFFSET) << 8;
-	outb(reg, data->addr + ADDR_REG_OFFSET);
-	val |= inb(data->addr + DATA_REG_OFFSET);
+	val  = f71882fg_read8(data, reg) << 8;
+	val |= f71882fg_read8(data, reg + 1);
 
 	return val;
 }
@@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
 
 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
 {
-	outb(reg++, data->addr + ADDR_REG_OFFSET);
-	outb(val >> 8, data->addr + DATA_REG_OFFSET);
-	outb(reg, data->addr + ADDR_REG_OFFSET);
-	outb(val & 255, data->addr + DATA_REG_OFFSET);
+	f71882fg_write8(data, reg,     val >> 8);
+	f71882fg_write8(data, reg + 1, val & 0xff);
 }
 
 static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH] hwmon: f71882fg: code cleanup
@ 2010-03-24  9:09       ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Some code cleanup: properly using previously defined functions, rather
than duplicating their code.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   18 ++++++------------
 1 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 4230729..ca34e5c 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg)
 static int superio_inw(int base, int reg)
 {
 	int val;
-	outb(reg++, base);
-	val = inb(base + 1) << 8;
-	outb(reg, base);
-	val |= inb(base + 1);
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
 	return val;
 }
 
@@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
 {
 	u16 val;
 
-	outb(reg++, data->addr + ADDR_REG_OFFSET);
-	val = inb(data->addr + DATA_REG_OFFSET) << 8;
-	outb(reg, data->addr + ADDR_REG_OFFSET);
-	val |= inb(data->addr + DATA_REG_OFFSET);
+	val  = f71882fg_read8(data, reg) << 8;
+	val |= f71882fg_read8(data, reg + 1);
 
 	return val;
 }
@@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
 
 static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
 {
-	outb(reg++, data->addr + ADDR_REG_OFFSET);
-	outb(val >> 8, data->addr + DATA_REG_OFFSET);
-	outb(reg, data->addr + ADDR_REG_OFFSET);
-	outb(val & 255, data->addr + DATA_REG_OFFSET);
+	f71882fg_write8(data, reg,     val >> 8);
+	f71882fg_write8(data, reg + 1, val & 0xff);
 }
 
 static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH] hwmon: f71882fg: acquire I/O regions while we're working with them
  2010-03-24  8:46     ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
@ 2010-03-24  9:09       ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Acquire the I/O region for the Super I/O chip while we're working on it.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index ca34e5c..fe7b671 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2178,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	int err = -ENODEV;
 	u16 devid;
 
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_region(sioaddr, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)sioaddr);
+		return -EIO;
+	}
+
 	superio_enter(sioaddr);
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
@@ -2232,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
+	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH] hwmon: f71882fg: acquire I/O regions while
@ 2010-03-24  9:09       ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Acquire the I/O region for the Super I/O chip while we're working on it.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index ca34e5c..fe7b671 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2178,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	int err = -ENODEV;
 	u16 devid;
 
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_region(sioaddr, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)sioaddr);
+		return -EIO;
+	}
+
 	superio_enter(sioaddr);
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
@@ -2232,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
+	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-03-24  8:25       ` [lm-sensors] [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for Hans de Goede
@ 2010-03-24  9:23         ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:23 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 12018 bytes --]

On Wed, Mar 24, 2010 at 09:25:08AM +0100, Hans de Goede wrote:
> See comments inline.
> 
> On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
>> Allow device probing to recognise the Fintek F71808E.
>> 
>> Sysfs interface:
>>   * Fan/pwm control is the same as for F71889FG
>>   * Temperature and voltage sensor handling is largely the same as for
>>     the F71889FG
>>    - Has one temperature sensor less (doesn't have temp3)
>>    - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>      what in7_input refers for F71889FG)
>> 
>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>> such that it can largely be reused.
>> ---
>>   Documentation/hwmon/f71882fg |    4 ++
>>   drivers/hwmon/Kconfig        |    6 ++--
>>   drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>>   3 files changed, 79 insertions(+), 11 deletions(-)
>> 
>> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
>> index 25e1cad..b290b87 100644
>> --- a/drivers/hwmon/f71882fg.c
>> +++ b/drivers/hwmon/f71882fg.c
>> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>>   			/* fall through! */
>>   		case f71862fg:
>>   			err = f71882fg_create_sysfs_files(pdev,
>> -					fxxxx_in_temp_attr,
>> -					ARRAY_SIZE(fxxxx_in_temp_attr));
>> +					f71862_temp_attr,
>> +					ARRAY_SIZE(f71862_temp_attr));
>> +			if (err)
>> +				goto exit_unregister_sysfs;
>> +			err = f71882fg_create_sysfs_files(pdev,
>> +					fxxxx_in_attr,
>> +					ARRAY_SIZE(fxxxx_in_attr));
>> +			if (err)
>> +				goto exit_unregister_sysfs;
>> +			/* fall through! */
> 
> Ugh, please don't fall through, and then have an if below to only do
> some parts of the case falling through. This is quite confusing
> at first I thought your code was buggy I had to read it twice to notice
> the if. Instead just duplicate the following lines:
>> +			err = f71882fg_create_sysfs_files(pdev,
>> +					fxxxx_temp_attr,
>> +					ARRAY_SIZE(fxxxx_temp_attr));
> In the f71862fg case, end the f71862fg case with a break and remove
> the if test from the f71808fg case.
> 
>> +		case f71808fg:
>> +			if (data->type == f71808fg) {
>> +				err = f71882fg_create_sysfs_files(pdev,
>> +						f71808_in_attr,
>> +						ARRAY_SIZE(f71808_in_attr));
>> +				if (err)
>> +					goto exit_unregister_sysfs;
>> +			}
>> +			err = f71882fg_create_sysfs_files(pdev,
>> +					fxxxx_temp_attr,
>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>   			break;
>>   		case f8000:
>>   			err = f71882fg_create_sysfs_files(pdev,
>> @@ -2126,8 +2175,20 @@ static int f71882fg_remove(struct platform_device *pdev)
>>   			/* fall through! */
>>   		case f71862fg:
>>   			f71882fg_remove_sysfs_files(pdev,
>> -					fxxxx_in_temp_attr,
>> -					ARRAY_SIZE(fxxxx_in_temp_attr));
>> +					f71862_temp_attr,
>> +					ARRAY_SIZE(f71862_temp_attr));
>> +			f71882fg_remove_sysfs_files(pdev,
>> +					fxxxx_in_attr,
>> +					ARRAY_SIZE(fxxxx_in_attr));
>> +			/* fall through! */
> 
> Idem.

Ack. New and improved patch follows this line.
========================================================================
hwmon: f71882fg: Add support for the Fintek F71808E

Allow device probing to recognise the Fintek F71808E.

Sysfs interface:
 * Fan/pwm control is the same as for F71889FG
 * Temperature and voltage sensor handling is largely the same as for
   the F71889FG
  - Has one temperature sensor less (doesn't have temp3)
  - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
    what in7_input refers for F71889FG)

For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
such that it can largely be reused.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 Documentation/hwmon/f71882fg |    4 ++
 drivers/hwmon/Kconfig        |    6 ++--
 drivers/hwmon/f71882fg.c     |   83 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index a7952c2..1a07fd6 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -2,6 +2,10 @@ Kernel driver f71882fg
 ======================
 
 Supported chips:
+  * Fintek F71808E
+    Prefix: 'f71808fg'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71858FG
     Prefix: 'f71858fg'
     Addresses scanned: none, address read from Super I/O config space
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e4595e6..7053608 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -332,11 +332,11 @@ config SENSORS_F71805F
 	  will be called f71805f.
 
 config SENSORS_F71882FG
-	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
+	tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
 	depends on EXPERIMENTAL
 	help
-	  If you say yes here you get support for hardware monitoring
-	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+	  If you say yes here you get support for hardware monitoring features
+	  of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
 	  F71889FG and F8000 Super-I/O chips.
 
 	  This driver can also be built as a module.  If so, the module
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 28bcbac..0b89bb6 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -45,6 +45,7 @@
 #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
 
 #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
@@ -96,9 +97,10 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
+	"f71808fg",
 	"f71858fg",
 	"f71862fg",
 	"f71882fg",
@@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 };
 
-/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
-static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
+/* In attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
 	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
 	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* In attr for the f71808fg */
+static struct sensor_device_attribute_2 f71808_in_attr[] = {
+	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
+	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
+	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
+	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
+	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
+	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
+	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
+	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
 	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
 	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 1),
@@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 		store_temp_beep, 0, 6),
 	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
 	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
+};
+
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 f71862_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
 	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 3),
@@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
 				data->temp_type[1] = 6;
 				break;
 			}
+		} else if (data->type == f71808fg) {
+			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
+			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
+
 		} else {
 			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
 			if ((reg2 & 0x03) == 0x01)
@@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
 
 	val /= 1000;
 
-	if (data->type == f71889fg)
+	if (data->type == f71889fg
+	 || data->type == f71808fg)
 		val = SENSORS_LIMIT(val, -128, 127);
 	else
 		val = SENSORS_LIMIT(val, 0, 127);
@@ -1974,8 +2002,28 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
+			break;
+		case f71808fg:
+			err = f71882fg_create_sysfs_files(pdev,
+					f71808_in_attr,
+					ARRAY_SIZE(f71808_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
@@ -2002,6 +2050,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 		case f71862fg:
 			err = (data->pwm_enable & 0x15) != 0x15;
 			break;
+		case f71808fg:
 		case f71882fg:
 		case f71889fg:
 			err = 0;
@@ -2047,6 +2096,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 					f8000_auto_pwm_attr,
 					ARRAY_SIZE(f8000_auto_pwm_attr));
 			break;
+		case f71808fg:
 		case f71889fg:
 			for (i = 0; i < nr_fans; i++) {
 				data->pwm_auto_point_mapping[i] =
@@ -2126,8 +2176,22 @@ static int f71882fg_remove(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			f71882fg_remove_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
+			break;
+		case f71808fg:
+			f71882fg_remove_sysfs_files(pdev,
+					f71808_in_attr,
+					ARRAY_SIZE(f71808_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			f71882fg_remove_sysfs_files(pdev,
@@ -2195,6 +2259,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
 	switch (devid) {
+	case SIO_F71808_ID:
+		sio_data->type = f71808fg;
+		break;
 	case SIO_F71858_ID:
 		sio_data->type = f71858fg;
 		break;
-- 
1.6.4.4


-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the
@ 2010-03-24  9:23         ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:23 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 12018 bytes --]

On Wed, Mar 24, 2010 at 09:25:08AM +0100, Hans de Goede wrote:
> See comments inline.
> 
> On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
>> Allow device probing to recognise the Fintek F71808E.
>> 
>> Sysfs interface:
>>   * Fan/pwm control is the same as for F71889FG
>>   * Temperature and voltage sensor handling is largely the same as for
>>     the F71889FG
>>    - Has one temperature sensor less (doesn't have temp3)
>>    - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>      what in7_input refers for F71889FG)
>> 
>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>> such that it can largely be reused.
>> ---
>>   Documentation/hwmon/f71882fg |    4 ++
>>   drivers/hwmon/Kconfig        |    6 ++--
>>   drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>>   3 files changed, 79 insertions(+), 11 deletions(-)
>> 
>> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
>> index 25e1cad..b290b87 100644
>> --- a/drivers/hwmon/f71882fg.c
>> +++ b/drivers/hwmon/f71882fg.c
>> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>>   			/* fall through! */
>>   		case f71862fg:
>>   			err = f71882fg_create_sysfs_files(pdev,
>> -					fxxxx_in_temp_attr,
>> -					ARRAY_SIZE(fxxxx_in_temp_attr));
>> +					f71862_temp_attr,
>> +					ARRAY_SIZE(f71862_temp_attr));
>> +			if (err)
>> +				goto exit_unregister_sysfs;
>> +			err = f71882fg_create_sysfs_files(pdev,
>> +					fxxxx_in_attr,
>> +					ARRAY_SIZE(fxxxx_in_attr));
>> +			if (err)
>> +				goto exit_unregister_sysfs;
>> +			/* fall through! */
> 
> Ugh, please don't fall through, and then have an if below to only do
> some parts of the case falling through. This is quite confusing
> at first I thought your code was buggy I had to read it twice to notice
> the if. Instead just duplicate the following lines:
>> +			err = f71882fg_create_sysfs_files(pdev,
>> +					fxxxx_temp_attr,
>> +					ARRAY_SIZE(fxxxx_temp_attr));
> In the f71862fg case, end the f71862fg case with a break and remove
> the if test from the f71808fg case.
> 
>> +		case f71808fg:
>> +			if (data->type == f71808fg) {
>> +				err = f71882fg_create_sysfs_files(pdev,
>> +						f71808_in_attr,
>> +						ARRAY_SIZE(f71808_in_attr));
>> +				if (err)
>> +					goto exit_unregister_sysfs;
>> +			}
>> +			err = f71882fg_create_sysfs_files(pdev,
>> +					fxxxx_temp_attr,
>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>   			break;
>>   		case f8000:
>>   			err = f71882fg_create_sysfs_files(pdev,
>> @@ -2126,8 +2175,20 @@ static int f71882fg_remove(struct platform_device *pdev)
>>   			/* fall through! */
>>   		case f71862fg:
>>   			f71882fg_remove_sysfs_files(pdev,
>> -					fxxxx_in_temp_attr,
>> -					ARRAY_SIZE(fxxxx_in_temp_attr));
>> +					f71862_temp_attr,
>> +					ARRAY_SIZE(f71862_temp_attr));
>> +			f71882fg_remove_sysfs_files(pdev,
>> +					fxxxx_in_attr,
>> +					ARRAY_SIZE(fxxxx_in_attr));
>> +			/* fall through! */
> 
> Idem.

Ack. New and improved patch follows this line.
========================================================================
hwmon: f71882fg: Add support for the Fintek F71808E

Allow device probing to recognise the Fintek F71808E.

Sysfs interface:
 * Fan/pwm control is the same as for F71889FG
 * Temperature and voltage sensor handling is largely the same as for
   the F71889FG
  - Has one temperature sensor less (doesn't have temp3)
  - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
    what in7_input refers for F71889FG)

For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
such that it can largely be reused.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 Documentation/hwmon/f71882fg |    4 ++
 drivers/hwmon/Kconfig        |    6 ++--
 drivers/hwmon/f71882fg.c     |   83 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index a7952c2..1a07fd6 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -2,6 +2,10 @@ Kernel driver f71882fg
 ======================
 
 Supported chips:
+  * Fintek F71808E
+    Prefix: 'f71808fg'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71858FG
     Prefix: 'f71858fg'
     Addresses scanned: none, address read from Super I/O config space
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e4595e6..7053608 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -332,11 +332,11 @@ config SENSORS_F71805F
 	  will be called f71805f.
 
 config SENSORS_F71882FG
-	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
+	tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
 	depends on EXPERIMENTAL
 	help
-	  If you say yes here you get support for hardware monitoring
-	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+	  If you say yes here you get support for hardware monitoring features
+	  of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
 	  F71889FG and F8000 Super-I/O chips.
 
 	  This driver can also be built as a module.  If so, the module
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 28bcbac..0b89bb6 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -45,6 +45,7 @@
 #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
 
 #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
@@ -96,9 +97,10 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
+	"f71808fg",
 	"f71858fg",
 	"f71862fg",
 	"f71882fg",
@@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 };
 
-/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
-static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
+/* In attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
 	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
 	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* In attr for the f71808fg */
+static struct sensor_device_attribute_2 f71808_in_attr[] = {
+	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
+	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
+	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
+	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
+	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
+	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
+	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
+	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
 	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
 	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 1),
@@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 		store_temp_beep, 0, 6),
 	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
 	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
+};
+
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 f71862_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
 	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 3),
@@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
 				data->temp_type[1] = 6;
 				break;
 			}
+		} else if (data->type == f71808fg) {
+			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
+			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
+
 		} else {
 			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
 			if ((reg2 & 0x03) == 0x01)
@@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
 
 	val /= 1000;
 
-	if (data->type == f71889fg)
+	if (data->type == f71889fg
+	 || data->type == f71808fg)
 		val = SENSORS_LIMIT(val, -128, 127);
 	else
 		val = SENSORS_LIMIT(val, 0, 127);
@@ -1974,8 +2002,28 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
+			break;
+		case f71808fg:
+			err = f71882fg_create_sysfs_files(pdev,
+					f71808_in_attr,
+					ARRAY_SIZE(f71808_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
@@ -2002,6 +2050,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 		case f71862fg:
 			err = (data->pwm_enable & 0x15) != 0x15;
 			break;
+		case f71808fg:
 		case f71882fg:
 		case f71889fg:
 			err = 0;
@@ -2047,6 +2096,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 					f8000_auto_pwm_attr,
 					ARRAY_SIZE(f8000_auto_pwm_attr));
 			break;
+		case f71808fg:
 		case f71889fg:
 			for (i = 0; i < nr_fans; i++) {
 				data->pwm_auto_point_mapping[i] =
@@ -2126,8 +2176,22 @@ static int f71882fg_remove(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			f71882fg_remove_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
+			break;
+		case f71808fg:
+			f71882fg_remove_sysfs_files(pdev,
+					f71808_in_attr,
+					ARRAY_SIZE(f71808_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			f71882fg_remove_sysfs_files(pdev,
@@ -2195,6 +2259,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
 	switch (devid) {
+	case SIO_F71808_ID:
+		sio_data->type = f71808fg;
+		break;
 	case SIO_F71858_ID:
 		sio_data->type = f71858fg;
 		break;
-- 
1.6.4.4


-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: properly acquire I/O regions while  probing
  2010-03-24  8:46     ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
@ 2010-03-24  9:28       ` Jean Delvare
  -1 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-03-24  9:28 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi Giel,

On Wed, 24 Mar 2010 09:46:43 +0100, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 09:14:14AM +0100, Hans de Goede wrote:
> > I don't have any objections against the proposed changes, but there
> > are 3 unrelated changes in this patch, please break them up in
> > separate patches:
> > 
> > 1) code cleanup: properly using, previously defined, functions rather
> >    than duplicating their code.
> > 2) properly acquire I/O regions while probing
> > 3) Make the addresses to probe an array
> > 
> > And IMHO you might just as well drop number 3, it does not really make
> > the code any better readable, and the old way is how all superio hwmon
> > drivers do things.
> 
> Okay, broken up patches will follow as replies to this message.
> 
> Regarding number (3), my goal wasn't to put the probe addresses in an
> array. My goal (as I think should have been made clear by the commit
> message I had added) was to make sure that upon failure f71882fg_find's
> return value gets passed back from the module's init function. This to
> make sure the *proper* error code gets passed back to the user of
> insmod/modprobe (as opposed to it being replaced by -ENODEV).

This doesn't make much sense. We call f71882fg_find up to twice, so we
can get up to 2 error codes, but the module init function can only
return one. There is no rationale for favoring the value returned by
the second call over the value returned by the first call. So it seems
reasonable to return an arbitrary error code. Of course we could spend
code comparing the error values and returning the right one if the two
functions returned the same error value, and only use the arbitrary
default if they returned different values. But honestly I don't see any
point in doing this in practice. Let's just log errors other than
-ENODEV so that the user can see the exact cause of failure in the
kernel log.

> Further I think non -ENODEV errors should probably immediately result in
> module initialisation failing (rather than retrying a probe), that's a
> design choice though (which my patch doesn't bother addressing right
> now).

I disagree. If the probe of 0x2e/0x2f fails because that region was busy,
this should not prevent us from giving a try to region 0x4e/0x4f. I
can't think of any error that would warrant avoiding the probe at
0x4e/0x4f. Worse thing that can happen is that the second probe fails
too. No big deal.

> However, regarding the for-loop/array thing, the same behaviour can be
> aqcuired with a patch like the one following this line. (Please tell me
> if you like this approach or something similar better. Though,
> personally, I think it's "hackisher"/dirtier).
> 
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 4230729..42d6304 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -2295,9 +2295,11 @@ static int __init f71882fg_init(void)
>  
>         memset(&sio_data, 0, sizeof(sio_data));
>  
> -       if (f71882fg_find(0x2e, &address, &sio_data) &&
> -           f71882fg_find(0x4e, &address, &sio_data))
> -               goto exit;
> +       if (f71882fg_find(0x2e, &address, &sio_data)) {
> +               err = f71882fg_find(0x4e, &address, &sio_data);
> +               if (err)
> +                       goto exit;
> +       }
>  
>         err = platform_driver_register(&f71882fg_driver);
>         if (err)
> 

I don't like either implementation, I would leave the code as it is
today.

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O
@ 2010-03-24  9:28       ` Jean Delvare
  0 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-03-24  9:28 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi Giel,

On Wed, 24 Mar 2010 09:46:43 +0100, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 09:14:14AM +0100, Hans de Goede wrote:
> > I don't have any objections against the proposed changes, but there
> > are 3 unrelated changes in this patch, please break them up in
> > separate patches:
> > 
> > 1) code cleanup: properly using, previously defined, functions rather
> >    than duplicating their code.
> > 2) properly acquire I/O regions while probing
> > 3) Make the addresses to probe an array
> > 
> > And IMHO you might just as well drop number 3, it does not really make
> > the code any better readable, and the old way is how all superio hwmon
> > drivers do things.
> 
> Okay, broken up patches will follow as replies to this message.
> 
> Regarding number (3), my goal wasn't to put the probe addresses in an
> array. My goal (as I think should have been made clear by the commit
> message I had added) was to make sure that upon failure f71882fg_find's
> return value gets passed back from the module's init function. This to
> make sure the *proper* error code gets passed back to the user of
> insmod/modprobe (as opposed to it being replaced by -ENODEV).

This doesn't make much sense. We call f71882fg_find up to twice, so we
can get up to 2 error codes, but the module init function can only
return one. There is no rationale for favoring the value returned by
the second call over the value returned by the first call. So it seems
reasonable to return an arbitrary error code. Of course we could spend
code comparing the error values and returning the right one if the two
functions returned the same error value, and only use the arbitrary
default if they returned different values. But honestly I don't see any
point in doing this in practice. Let's just log errors other than
-ENODEV so that the user can see the exact cause of failure in the
kernel log.

> Further I think non -ENODEV errors should probably immediately result in
> module initialisation failing (rather than retrying a probe), that's a
> design choice though (which my patch doesn't bother addressing right
> now).

I disagree. If the probe of 0x2e/0x2f fails because that region was busy,
this should not prevent us from giving a try to region 0x4e/0x4f. I
can't think of any error that would warrant avoiding the probe at
0x4e/0x4f. Worse thing that can happen is that the second probe fails
too. No big deal.

> However, regarding the for-loop/array thing, the same behaviour can be
> aqcuired with a patch like the one following this line. (Please tell me
> if you like this approach or something similar better. Though,
> personally, I think it's "hackisher"/dirtier).
> 
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 4230729..42d6304 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -2295,9 +2295,11 @@ static int __init f71882fg_init(void)
>  
>         memset(&sio_data, 0, sizeof(sio_data));
>  
> -       if (f71882fg_find(0x2e, &address, &sio_data) &&
> -           f71882fg_find(0x4e, &address, &sio_data))
> -               goto exit;
> +       if (f71882fg_find(0x2e, &address, &sio_data)) {
> +               err = f71882fg_find(0x4e, &address, &sio_data);
> +               if (err)
> +                       goto exit;
> +       }
>  
>         err = platform_driver_register(&f71882fg_driver);
>         if (err)
> 

I don't like either implementation, I would leave the code as it is
today.

-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing
  2010-03-23 14:12 ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O regions Giel van Schijndel
@ 2010-03-24  9:29   ` Jean Delvare
  -1 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-03-24  9:29 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

On Tue, 23 Mar 2010 15:12:15 +0100, Giel van Schijndel wrote:
> Acquire the I/O region for the Super I/O chip while we're working on it.
> 
> Further alter the way multiple Super I/O addresses are probed for chips
> such that errors in the probing process are passed on from the module
> initialisation function.
> 
> Some code cleanup: properly using, previously defined, functions rather
> than duplicating their code.
> (...)

On top of Hans' comments, to which I agree:

>  static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
> @@ -2184,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>  	int err = -ENODEV;
>  	u16 devid;
>  
> +	/* Don't step on other driver's I/O space by accident */
> +	if (!request_region(sioaddr, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				(int)sioaddr);
> +		return -EIO;

This is the wrong error code. This isn't an I/O error. You want -EBUSY.

> +	}
> +
>  	superio_enter(sioaddr);
>  
>  	devid = superio_inw(sioaddr, SIO_REG_MANID);

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O
@ 2010-03-24  9:29   ` Jean Delvare
  0 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-03-24  9:29 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

On Tue, 23 Mar 2010 15:12:15 +0100, Giel van Schijndel wrote:
> Acquire the I/O region for the Super I/O chip while we're working on it.
> 
> Further alter the way multiple Super I/O addresses are probed for chips
> such that errors in the probing process are passed on from the module
> initialisation function.
> 
> Some code cleanup: properly using, previously defined, functions rather
> than duplicating their code.
> (...)

On top of Hans' comments, to which I agree:

>  static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
> @@ -2184,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>  	int err = -ENODEV;
>  	u16 devid;
>  
> +	/* Don't step on other driver's I/O space by accident */
> +	if (!request_region(sioaddr, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				(int)sioaddr);
> +		return -EIO;

This is the wrong error code. This isn't an I/O error. You want -EBUSY.

> +	}
> +
>  	superio_enter(sioaddr);
>  
>  	devid = superio_inw(sioaddr, SIO_REG_MANID);

-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing
  2010-03-24  9:29   ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Jean Delvare
@ 2010-03-24  9:34     ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:34 UTC (permalink / raw)
  To: Jean Delvare
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1970 bytes --]

On Wed, Mar 24, 2010 at 10:29:42AM +0100, Jean Delvare wrote:
> On Tue, 23 Mar 2010 15:12:15 +0100, Giel van Schijndel wrote:
>>  static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
>> @@ -2184,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>>  	int err = -ENODEV;
>>  	u16 devid;
>>  
>> +	/* Don't step on other driver's I/O space by accident */
>> +	if (!request_region(sioaddr, 2, DRVNAME)) {
>> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
>> +				(int)sioaddr);
>> +		return -EIO;
> 
> This is the wrong error code. This isn't an I/O error. You want -EBUSY.

Ack. New patch follows this line.
========================================================================
hwmon: f71882fg: acquire I/O regions while we're working with them

Acquire the I/O region for the Super I/O chip while we're working on it.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index ca34e5c..537841e 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2178,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	int err = -ENODEV;
 	u16 devid;
 
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_region(sioaddr, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)sioaddr);
+		return -EBUSY;
+	}
+
 	superio_enter(sioaddr);
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
@@ -2232,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
+	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O
@ 2010-03-24  9:34     ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:34 UTC (permalink / raw)
  To: Jean Delvare
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1970 bytes --]

On Wed, Mar 24, 2010 at 10:29:42AM +0100, Jean Delvare wrote:
> On Tue, 23 Mar 2010 15:12:15 +0100, Giel van Schijndel wrote:
>>  static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
>> @@ -2184,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>>  	int err = -ENODEV;
>>  	u16 devid;
>>  
>> +	/* Don't step on other driver's I/O space by accident */
>> +	if (!request_region(sioaddr, 2, DRVNAME)) {
>> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
>> +				(int)sioaddr);
>> +		return -EIO;
> 
> This is the wrong error code. This isn't an I/O error. You want -EBUSY.

Ack. New patch follows this line.
========================================================================
hwmon: f71882fg: acquire I/O regions while we're working with them

Acquire the I/O region for the Super I/O chip while we're working on it.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index ca34e5c..537841e 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2178,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	int err = -ENODEV;
 	u16 devid;
 
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_region(sioaddr, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)sioaddr);
+		return -EBUSY;
+	}
+
 	superio_enter(sioaddr);
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
@@ -2232,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
+	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-24  8:37             ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Hans de Goede
@ 2010-03-24  9:36               ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:36 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 419 bytes --]

On Wed, Mar 24, 2010 at 09:37:43AM +0100, Hans de Goede wrote:
> Nack:
> As the watchdog has its own SIO logical device number, it should
> have a separate driver, not have support glued to the hwmon driver.

Thus, if I understand correctly, you would suggest for me to implement a
new driver in drivers/watchdog/ to implement this driver?

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-24  9:36               ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24  9:36 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 419 bytes --]

On Wed, Mar 24, 2010 at 09:37:43AM +0100, Hans de Goede wrote:
> Nack:
> As the watchdog has its own SIO logical device number, it should
> have a separate driver, not have support glued to the hwmon driver.

Thus, if I understand correctly, you would suggest for me to implement a
new driver in drivers/watchdog/ to implement this driver?

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-03-24  9:23         ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Giel van Schijndel
@ 2010-03-24 10:31           ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24 10:31 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

On 03/24/2010 10:23 AM, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 09:25:08AM +0100, Hans de Goede wrote:
>> See comments inline.
>>
>> On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
>>> Allow device probing to recognise the Fintek F71808E.
>>>
>>> Sysfs interface:
>>>    * Fan/pwm control is the same as for F71889FG
>>>    * Temperature and voltage sensor handling is largely the same as for
>>>      the F71889FG
>>>     - Has one temperature sensor less (doesn't have temp3)
>>>     - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>>       what in7_input refers for F71889FG)
>>>
>>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>>> such that it can largely be reused.
>>> ---
>>>    Documentation/hwmon/f71882fg |    4 ++
>>>    drivers/hwmon/Kconfig        |    6 ++--
>>>    drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>>>    3 files changed, 79 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
>>> index 25e1cad..b290b87 100644
>>> --- a/drivers/hwmon/f71882fg.c
>>> +++ b/drivers/hwmon/f71882fg.c
>>> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>>>    			/* fall through! */
>>>    		case f71862fg:
>>>    			err = f71882fg_create_sysfs_files(pdev,
>>> -					fxxxx_in_temp_attr,
>>> -					ARRAY_SIZE(fxxxx_in_temp_attr));
>>> +					f71862_temp_attr,
>>> +					ARRAY_SIZE(f71862_temp_attr));
>>> +			if (err)
>>> +				goto exit_unregister_sysfs;
>>> +			err = f71882fg_create_sysfs_files(pdev,
>>> +					fxxxx_in_attr,
>>> +					ARRAY_SIZE(fxxxx_in_attr));
>>> +			if (err)
>>> +				goto exit_unregister_sysfs;
>>> +			/* fall through! */
>>
>> Ugh, please don't fall through, and then have an if below to only do
>> some parts of the case falling through. This is quite confusing
>> at first I thought your code was buggy I had to read it twice to notice
>> the if. Instead just duplicate the following lines:
>>> +			err = f71882fg_create_sysfs_files(pdev,
>>> +					fxxxx_temp_attr,
>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>> In the f71862fg case, end the f71862fg case with a break and remove
>> the if test from the f71808fg case.
>>
>>> +		case f71808fg:
>>> +			if (data->type == f71808fg) {
>>> +				err = f71882fg_create_sysfs_files(pdev,
>>> +						f71808_in_attr,
>>> +						ARRAY_SIZE(f71808_in_attr));
>>> +				if (err)
>>> +					goto exit_unregister_sysfs;
>>> +			}
>>> +			err = f71882fg_create_sysfs_files(pdev,
>>> +					fxxxx_temp_attr,
>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>>    			break;
>>>    		case f8000:
>>>    			err = f71882fg_create_sysfs_files(pdev,
>>> @@ -2126,8 +2175,20 @@ static int f71882fg_remove(struct platform_device *pdev)
>>>    			/* fall through! */
>>>    		case f71862fg:
>>>    			f71882fg_remove_sysfs_files(pdev,
>>> -					fxxxx_in_temp_attr,
>>> -					ARRAY_SIZE(fxxxx_in_temp_attr));
>>> +					f71862_temp_attr,
>>> +					ARRAY_SIZE(f71862_temp_attr));
>>> +			f71882fg_remove_sysfs_files(pdev,
>>> +					fxxxx_in_attr,
>>> +					ARRAY_SIZE(fxxxx_in_attr));
>>> +			/* fall through! */
>>
>> Idem.
>
> Ack. New and improved patch follows this line.
> ========================================================================
> hwmon: f71882fg: Add support for the Fintek F71808E
>

This new version looks good to me:
Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the
@ 2010-03-24 10:31           ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24 10:31 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

On 03/24/2010 10:23 AM, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 09:25:08AM +0100, Hans de Goede wrote:
>> See comments inline.
>>
>> On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
>>> Allow device probing to recognise the Fintek F71808E.
>>>
>>> Sysfs interface:
>>>    * Fan/pwm control is the same as for F71889FG
>>>    * Temperature and voltage sensor handling is largely the same as for
>>>      the F71889FG
>>>     - Has one temperature sensor less (doesn't have temp3)
>>>     - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>>       what in7_input refers for F71889FG)
>>>
>>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>>> such that it can largely be reused.
>>> ---
>>>    Documentation/hwmon/f71882fg |    4 ++
>>>    drivers/hwmon/Kconfig        |    6 ++--
>>>    drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>>>    3 files changed, 79 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
>>> index 25e1cad..b290b87 100644
>>> --- a/drivers/hwmon/f71882fg.c
>>> +++ b/drivers/hwmon/f71882fg.c
>>> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>>>    			/* fall through! */
>>>    		case f71862fg:
>>>    			err = f71882fg_create_sysfs_files(pdev,
>>> -					fxxxx_in_temp_attr,
>>> -					ARRAY_SIZE(fxxxx_in_temp_attr));
>>> +					f71862_temp_attr,
>>> +					ARRAY_SIZE(f71862_temp_attr));
>>> +			if (err)
>>> +				goto exit_unregister_sysfs;
>>> +			err = f71882fg_create_sysfs_files(pdev,
>>> +					fxxxx_in_attr,
>>> +					ARRAY_SIZE(fxxxx_in_attr));
>>> +			if (err)
>>> +				goto exit_unregister_sysfs;
>>> +			/* fall through! */
>>
>> Ugh, please don't fall through, and then have an if below to only do
>> some parts of the case falling through. This is quite confusing
>> at first I thought your code was buggy I had to read it twice to notice
>> the if. Instead just duplicate the following lines:
>>> +			err = f71882fg_create_sysfs_files(pdev,
>>> +					fxxxx_temp_attr,
>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>> In the f71862fg case, end the f71862fg case with a break and remove
>> the if test from the f71808fg case.
>>
>>> +		case f71808fg:
>>> +			if (data->type = f71808fg) {
>>> +				err = f71882fg_create_sysfs_files(pdev,
>>> +						f71808_in_attr,
>>> +						ARRAY_SIZE(f71808_in_attr));
>>> +				if (err)
>>> +					goto exit_unregister_sysfs;
>>> +			}
>>> +			err = f71882fg_create_sysfs_files(pdev,
>>> +					fxxxx_temp_attr,
>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>>    			break;
>>>    		case f8000:
>>>    			err = f71882fg_create_sysfs_files(pdev,
>>> @@ -2126,8 +2175,20 @@ static int f71882fg_remove(struct platform_device *pdev)
>>>    			/* fall through! */
>>>    		case f71862fg:
>>>    			f71882fg_remove_sysfs_files(pdev,
>>> -					fxxxx_in_temp_attr,
>>> -					ARRAY_SIZE(fxxxx_in_temp_attr));
>>> +					f71862_temp_attr,
>>> +					ARRAY_SIZE(f71862_temp_attr));
>>> +			f71882fg_remove_sysfs_files(pdev,
>>> +					fxxxx_in_attr,
>>> +					ARRAY_SIZE(fxxxx_in_attr));
>>> +			/* fall through! */
>>
>> Idem.
>
> Ack. New and improved patch follows this line.
> ====================================
> hwmon: f71882fg: Add support for the Fintek F71808E
>

This new version looks good to me:
Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-24  9:36               ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
@ 2010-03-24 10:33                 ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24 10:33 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

On 03/24/2010 10:36 AM, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 09:37:43AM +0100, Hans de Goede wrote:
>> Nack:
>> As the watchdog has its own SIO logical device number, it should
>> have a separate driver, not have support glued to the hwmon driver.
>
> Thus, if I understand correctly, you would suggest for me to implement a
> new driver in drivers/watchdog/ to implement this driver?
>

Yes, correct.

Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-24 10:33                 ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24 10:33 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

On 03/24/2010 10:36 AM, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 09:37:43AM +0100, Hans de Goede wrote:
>> Nack:
>> As the watchdog has its own SIO logical device number, it should
>> have a separate driver, not have support glued to the hwmon driver.
>
> Thus, if I understand correctly, you would suggest for me to implement a
> new driver in drivers/watchdog/ to implement this driver?
>

Yes, correct.

Regards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: code cleanup
  2010-03-24  9:09       ` [lm-sensors] " Giel van Schijndel
@ 2010-03-24 12:54         ` Jean Delvare
  -1 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-03-24 12:54 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

On Wed, 24 Mar 2010 10:09:01 +0100, Giel van Schijndel wrote:
> Some code cleanup: properly using previously defined functions, rather
> than duplicating their code.
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>
> ---
>  drivers/hwmon/f71882fg.c |   18 ++++++------------
>  1 files changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 4230729..ca34e5c 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg)
>  static int superio_inw(int base, int reg)
>  {
>  	int val;
> -	outb(reg++, base);
> -	val = inb(base + 1) << 8;
> -	outb(reg, base);
> -	val |= inb(base + 1);
> +	val  = superio_inb(base, reg) << 8;
> +	val |= superio_inb(base, reg + 1);
>  	return val;
>  }
>  
> @@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
>  {
>  	u16 val;
>  
> -	outb(reg++, data->addr + ADDR_REG_OFFSET);
> -	val = inb(data->addr + DATA_REG_OFFSET) << 8;
> -	outb(reg, data->addr + ADDR_REG_OFFSET);
> -	val |= inb(data->addr + DATA_REG_OFFSET);
> +	val  = f71882fg_read8(data, reg) << 8;
> +	val |= f71882fg_read8(data, reg + 1);
>  
>  	return val;
>  }
> @@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
>  
>  static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
>  {
> -	outb(reg++, data->addr + ADDR_REG_OFFSET);
> -	outb(val >> 8, data->addr + DATA_REG_OFFSET);
> -	outb(reg, data->addr + ADDR_REG_OFFSET);
> -	outb(val & 255, data->addr + DATA_REG_OFFSET);
> +	f71882fg_write8(data, reg,     val >> 8);
> +	f71882fg_write8(data, reg + 1, val & 0xff);
>  }
>  
>  static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)

Applied, thanks.

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: code cleanup
@ 2010-03-24 12:54         ` Jean Delvare
  0 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-03-24 12:54 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

On Wed, 24 Mar 2010 10:09:01 +0100, Giel van Schijndel wrote:
> Some code cleanup: properly using previously defined functions, rather
> than duplicating their code.
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>
> ---
>  drivers/hwmon/f71882fg.c |   18 ++++++------------
>  1 files changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 4230729..ca34e5c 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -856,10 +856,8 @@ static inline int superio_inb(int base, int reg)
>  static int superio_inw(int base, int reg)
>  {
>  	int val;
> -	outb(reg++, base);
> -	val = inb(base + 1) << 8;
> -	outb(reg, base);
> -	val |= inb(base + 1);
> +	val  = superio_inb(base, reg) << 8;
> +	val |= superio_inb(base, reg + 1);
>  	return val;
>  }
>  
> @@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
>  {
>  	u16 val;
>  
> -	outb(reg++, data->addr + ADDR_REG_OFFSET);
> -	val = inb(data->addr + DATA_REG_OFFSET) << 8;
> -	outb(reg, data->addr + ADDR_REG_OFFSET);
> -	val |= inb(data->addr + DATA_REG_OFFSET);
> +	val  = f71882fg_read8(data, reg) << 8;
> +	val |= f71882fg_read8(data, reg + 1);
>  
>  	return val;
>  }
> @@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
>  
>  static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
>  {
> -	outb(reg++, data->addr + ADDR_REG_OFFSET);
> -	outb(val >> 8, data->addr + DATA_REG_OFFSET);
> -	outb(reg, data->addr + ADDR_REG_OFFSET);
> -	outb(val & 255, data->addr + DATA_REG_OFFSET);
> +	f71882fg_write8(data, reg,     val >> 8);
> +	f71882fg_write8(data, reg + 1, val & 0xff);
>  }
>  
>  static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)

Applied, thanks.

-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: properly acquire I/O regions while  probing
  2010-03-24  9:34     ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
@ 2010-03-24 12:54       ` Jean Delvare
  -1 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-03-24 12:54 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

On Wed, 24 Mar 2010 10:34:37 +0100, Giel van Schijndel wrote:
> hwmon: f71882fg: acquire I/O regions while we're working with them
> 
> Acquire the I/O region for the Super I/O chip while we're working on it.
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>
> ---
>  drivers/hwmon/f71882fg.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index ca34e5c..537841e 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -2178,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>  	int err = -ENODEV;
>  	u16 devid;
>  
> +	/* Don't step on other drivers' I/O space by accident */
> +	if (!request_region(sioaddr, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				(int)sioaddr);
> +		return -EBUSY;
> +	}
> +
>  	superio_enter(sioaddr);
>  
>  	devid = superio_inw(sioaddr, SIO_REG_MANID);
> @@ -2232,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>  		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>  exit:
>  	superio_exit(sioaddr);
> +	release_region(sioaddr, 2);
>  	return err;
>  }
>  

Applied, thanks.

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O
@ 2010-03-24 12:54       ` Jean Delvare
  0 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-03-24 12:54 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

On Wed, 24 Mar 2010 10:34:37 +0100, Giel van Schijndel wrote:
> hwmon: f71882fg: acquire I/O regions while we're working with them
> 
> Acquire the I/O region for the Super I/O chip while we're working on it.
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>
> ---
>  drivers/hwmon/f71882fg.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index ca34e5c..537841e 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -2178,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>  	int err = -ENODEV;
>  	u16 devid;
>  
> +	/* Don't step on other drivers' I/O space by accident */
> +	if (!request_region(sioaddr, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				(int)sioaddr);
> +		return -EBUSY;
> +	}
> +
>  	superio_enter(sioaddr);
>  
>  	devid = superio_inw(sioaddr, SIO_REG_MANID);
> @@ -2232,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>  		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>  exit:
>  	superio_exit(sioaddr);
> +	release_region(sioaddr, 2);
>  	return err;
>  }
>  

Applied, thanks.

-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-24 10:33                 ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Hans de Goede
@ 2010-03-24 15:35                   ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24 15:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2542 bytes --]

On Wed, Mar 24, 2010 at 11:33:00AM +0100, Hans de Goede wrote:
> On 03/24/2010 10:36 AM, Giel van Schijndel wrote:
>>On Wed, Mar 24, 2010 at 09:37:43AM +0100, Hans de Goede wrote:
>>> Nack:
>>> As the watchdog has its own SIO logical device number, it should
>>> have a separate driver, not have support glued to the hwmon driver.
>>
>> Thus, if I understand correctly, you would suggest for me to
>> implement a new driver in drivers/watchdog/ to implement this
>> feature?
> 
> Yes, correct.

So I've now started out working on moving the watchdog code to a
separate driver.

  I/O port conflict

However, this driver would have to lock the SIO port range as well.
Unlike the hardware monitor, however, the watchdog (VID controller on
some datasheets) doesn't appear to provide for an alternative I/O port
mapping. Meaning the wathdog driver would have to maintain a permanent
hold on the SIO port range. This would thus interfere with the operation
of the f71882fg driver. I.e. it would prevent the device probing stage
from working, thus preventing it from loading *after* my in-development
watchdog driver.

  Alternative logical device port mapping

Regarding address mapping: the 16 bit SIO_REG_ADDR(0x60) register does
exist for this logical device, though according to the datasheet it is
set to 0x0000 by default. Reading the value from hardware it claims to
be mapped on 0x0AE0, trying to read from that port range (using
f71882fg_read8) yields nothing more than 0xFF for any register mentioned
in the datasheet.

  Hardware monitor alternate port range

Further, when looking at the way that SIO_REG_ADDR is currently used by
the f71882fg driver I get more confused:
> *hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
>     /* error checking: *hwmon_addr != 0 */
> *hwmon_addr &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */

For the F71808E and F71889, which both have 0x295, for hardware monitor
base address that code ^^ combined with the addition of ADDR_REG_OFFSET
and DATA_REG_OFFSET (see f71882fg_(read|write)8) all of this basically
amounts to mangling 0x295 -> 0x290 -> (0x295,0x296).

So my question: is there any particular reason for performing this
address mangling? Mostly: is there anything there that I should try
replicating in order to get mapping of the watchdog device on an
alternate port range working?

PS Perhaps this would be easier to converse about if you had the
   datasheet?

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-24 15:35                   ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24 15:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2542 bytes --]

On Wed, Mar 24, 2010 at 11:33:00AM +0100, Hans de Goede wrote:
> On 03/24/2010 10:36 AM, Giel van Schijndel wrote:
>>On Wed, Mar 24, 2010 at 09:37:43AM +0100, Hans de Goede wrote:
>>> Nack:
>>> As the watchdog has its own SIO logical device number, it should
>>> have a separate driver, not have support glued to the hwmon driver.
>>
>> Thus, if I understand correctly, you would suggest for me to
>> implement a new driver in drivers/watchdog/ to implement this
>> feature?
> 
> Yes, correct.

So I've now started out working on moving the watchdog code to a
separate driver.

  I/O port conflict

However, this driver would have to lock the SIO port range as well.
Unlike the hardware monitor, however, the watchdog (VID controller on
some datasheets) doesn't appear to provide for an alternative I/O port
mapping. Meaning the wathdog driver would have to maintain a permanent
hold on the SIO port range. This would thus interfere with the operation
of the f71882fg driver. I.e. it would prevent the device probing stage
from working, thus preventing it from loading *after* my in-development
watchdog driver.

  Alternative logical device port mapping

Regarding address mapping: the 16 bit SIO_REG_ADDR(0x60) register does
exist for this logical device, though according to the datasheet it is
set to 0x0000 by default. Reading the value from hardware it claims to
be mapped on 0x0AE0, trying to read from that port range (using
f71882fg_read8) yields nothing more than 0xFF for any register mentioned
in the datasheet.

  Hardware monitor alternate port range

Further, when looking at the way that SIO_REG_ADDR is currently used by
the f71882fg driver I get more confused:
> *hwmon_addr = superio_inw(sioaddr, SIO_REG_ADDR);
>     /* error checking: *hwmon_addr != 0 */
> *hwmon_addr &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */

For the F71808E and F71889, which both have 0x295, for hardware monitor
base address that code ^^ combined with the addition of ADDR_REG_OFFSET
and DATA_REG_OFFSET (see f71882fg_(read|write)8) all of this basically
amounts to mangling 0x295 -> 0x290 -> (0x295,0x296).

So my question: is there any particular reason for performing this
address mangling? Mostly: is there anything there that I should try
replicating in order to get mapping of the watchdog device on an
alternate port range working?

PS Perhaps this would be easier to converse about if you had the
   datasheet?

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-24 15:35                   ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
@ 2010-03-24 15:51                     ` Alan Cox
  -1 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-24 15:51 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

> hold on the SIO port range. This would thus interfere with the operation
> of the f71882fg driver. I.e. it would prevent the device probing stage
> from working, thus preventing it from loading *after* my in-development
> watchdog driver.

There are two ways to deal with that really

1. Add a multi-function driver - it finds the chip and claims the port
regions and then provides methods for locked access to them as well as
creating other device instances that the drivers map to (probably platform
devices ?) which in turn trigger the loading/binding of the relevant low
level devices.

2. Fix the kernel request_resource stuff to support a sleeping non
exclusive resource so request/free of regions can be used as a resource
semaphore by co-operative devices.

#2 is actually not hard but when I did the patch originally it then
wasn't needed by the driver I had in mind for other reasons.

See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea

Maybe its worth resurrecting ?

Alan

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-24 15:51                     ` Alan Cox
  0 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-24 15:51 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

> hold on the SIO port range. This would thus interfere with the operation
> of the f71882fg driver. I.e. it would prevent the device probing stage
> from working, thus preventing it from loading *after* my in-development
> watchdog driver.

There are two ways to deal with that really

1. Add a multi-function driver - it finds the chip and claims the port
regions and then provides methods for locked access to them as well as
creating other device instances that the drivers map to (probably platform
devices ?) which in turn trigger the loading/binding of the relevant low
level devices.

2. Fix the kernel request_resource stuff to support a sleeping non
exclusive resource so request/free of regions can be used as a resource
semaphore by co-operative devices.

#2 is actually not hard but when I did the patch originally it then
wasn't needed by the driver I had in mind for other reasons.

See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea

Maybe its worth resurrecting ?

Alan

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-24 15:51                     ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Alan Cox
@ 2010-03-24 16:20                       ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24 16:20 UTC (permalink / raw)
  To: Alan Cox
  Cc: Giel van Schijndel, Jean Delvare, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Hi,

On 03/24/2010 04:51 PM, Alan Cox wrote:
>> hold on the SIO port range. This would thus interfere with the operation
>> of the f71882fg driver. I.e. it would prevent the device probing stage
>> from working, thus preventing it from loading *after* my in-development
>> watchdog driver.
>
> There are two ways to deal with that really
>
> 1. Add a multi-function driver - it finds the chip and claims the port
> regions and then provides methods for locked access to them as well as
> creating other device instances that the drivers map to (probably platform
> devices ?) which in turn trigger the loading/binding of the relevant low
> level devices.
>
> 2. Fix the kernel request_resource stuff to support a sleeping non
> exclusive resource so request/free of regions can be used as a resource
> semaphore by co-operative devices.
>
> #2 is actually not hard but when I did the patch originally it then
> wasn't needed by the driver I had in mind for other reasons.
>
> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
>
> Maybe its worth resurrecting ?
>

Or, a bit more specific solution would be to resurrect the superio lock
coordinator patches, which were written (but never merged) 2 years ago
to solve exactly this problem:
http://lists.lm-sensors.org/pipermail/lm-sensors/2008-July/023743.html

Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-24 16:20                       ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-24 16:20 UTC (permalink / raw)
  To: Alan Cox
  Cc: Giel van Schijndel, Jean Delvare, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Hi,

On 03/24/2010 04:51 PM, Alan Cox wrote:
>> hold on the SIO port range. This would thus interfere with the operation
>> of the f71882fg driver. I.e. it would prevent the device probing stage
>> from working, thus preventing it from loading *after* my in-development
>> watchdog driver.
>
> There are two ways to deal with that really
>
> 1. Add a multi-function driver - it finds the chip and claims the port
> regions and then provides methods for locked access to them as well as
> creating other device instances that the drivers map to (probably platform
> devices ?) which in turn trigger the loading/binding of the relevant low
> level devices.
>
> 2. Fix the kernel request_resource stuff to support a sleeping non
> exclusive resource so request/free of regions can be used as a resource
> semaphore by co-operative devices.
>
> #2 is actually not hard but when I did the patch originally it then
> wasn't needed by the driver I had in mind for other reasons.
>
> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
>
> Maybe its worth resurrecting ?
>

Or, a bit more specific solution would be to resurrect the superio lock
coordinator patches, which were written (but never merged) 2 years ago
to solve exactly this problem:
http://lists.lm-sensors.org/pipermail/lm-sensors/2008-July/023743.html

Regards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-24 16:20                       ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Hans de Goede
@ 2010-03-24 20:35                         ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24 20:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Alan Cox, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2483 bytes --]

On Wed, Mar 24, 2010 at 05:20:59PM +0100, Hans de Goede wrote:
> On 03/24/2010 04:51 PM, Alan Cox wrote:
>>> hold on the SIO port range. This would thus interfere with the
>>> operation of the f71882fg driver. I.e. it would prevent the device
>>> probing stage from working, thus preventing it from loading *after*
>>> my in-development watchdog driver.
>> 
>> There are two ways to deal with that really
>> 
>> 1. Add a multi-function driver - it finds the chip and claims the
>> port regions and then provides methods for locked access to them as
>> well as creating other device instances that the drivers map to
>> (probably platform devices ?) which in turn trigger the
>> loading/binding of the relevant low level devices.
>> 
>> 2. Fix the kernel request_resource stuff to support a sleeping non
>> exclusive resource so request/free of regions can be used as a
>> resource semaphore by co-operative devices.
>> 
>> #2 is actually not hard but when I did the patch originally it then
>> wasn't needed by the driver I had in mind for other reasons.
>> 
>> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
>> 
>> Maybe its worth resurrecting ?
> 
> Or, a bit more specific solution would be to resurrect the superio
> lock coordinator patches, which were written (but never merged) 2
> years ago to solve exactly this problem:
> http://lists.lm-sensors.org/pipermail/lm-sensors/2008-July/023743.html

When performing some searches I find messages going back to at least
september 2006 [1] [2]. With multiple occurences of these patches being
"dusted off". They never got applied though, and for that (*not*
applying them) I cannot find any reason. Is there any? Or did people
just become uninterested and let the patches "collect dust"?

Then regarding Alan's patch. The fact that it is a *lot* simpler than
Jim Cromie's SuperIO locks coordinator is IMHO a significant advantage
over the latter. Furthermore, "lock coordinator" seems like a bad name
to me, since those patches seem especially concerned with centralising
the way that SuperIO devices are probed for. Thus if the only thing
required is to serialize resource access I think plain-ol' locking
(with the ability to block on the lock, rather than polling for it).

[1] http://lists.lm-sensors.org/pipermail/lm-sensors/2006-June/016476.html
[2] http://lkml.org/lkml/2006/9/14/20

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-24 20:35                         ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-24 20:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Alan Cox, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2483 bytes --]

On Wed, Mar 24, 2010 at 05:20:59PM +0100, Hans de Goede wrote:
> On 03/24/2010 04:51 PM, Alan Cox wrote:
>>> hold on the SIO port range. This would thus interfere with the
>>> operation of the f71882fg driver. I.e. it would prevent the device
>>> probing stage from working, thus preventing it from loading *after*
>>> my in-development watchdog driver.
>> 
>> There are two ways to deal with that really
>> 
>> 1. Add a multi-function driver - it finds the chip and claims the
>> port regions and then provides methods for locked access to them as
>> well as creating other device instances that the drivers map to
>> (probably platform devices ?) which in turn trigger the
>> loading/binding of the relevant low level devices.
>> 
>> 2. Fix the kernel request_resource stuff to support a sleeping non
>> exclusive resource so request/free of regions can be used as a
>> resource semaphore by co-operative devices.
>> 
>> #2 is actually not hard but when I did the patch originally it then
>> wasn't needed by the driver I had in mind for other reasons.
>> 
>> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
>> 
>> Maybe its worth resurrecting ?
> 
> Or, a bit more specific solution would be to resurrect the superio
> lock coordinator patches, which were written (but never merged) 2
> years ago to solve exactly this problem:
> http://lists.lm-sensors.org/pipermail/lm-sensors/2008-July/023743.html

When performing some searches I find messages going back to at least
september 2006 [1] [2]. With multiple occurences of these patches being
"dusted off". They never got applied though, and for that (*not*
applying them) I cannot find any reason. Is there any? Or did people
just become uninterested and let the patches "collect dust"?

Then regarding Alan's patch. The fact that it is a *lot* simpler than
Jim Cromie's SuperIO locks coordinator is IMHO a significant advantage
over the latter. Furthermore, "lock coordinator" seems like a bad name
to me, since those patches seem especially concerned with centralising
the way that SuperIO devices are probed for. Thus if the only thing
required is to serialize resource access I think plain-ol' locking
(with the ability to block on the lock, rather than polling for it).

[1] http://lists.lm-sensors.org/pipermail/lm-sensors/2006-June/016476.html
[2] http://lkml.org/lkml/2006/9/14/20

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-24 15:51                     ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Alan Cox
@ 2010-03-25  8:54                       ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25  8:54 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1589 bytes --]

On Wed, Mar 24, 2010 at 03:51:51PM +0000, Alan Cox wrote:
>> hold on the SIO port range. This would thus interfere with the
>> operation of the f71882fg driver. I.e. it would prevent the device
>> probing stage from working, thus preventing it from loading *after*
>> my in-development watchdog driver.
> 
> There are two ways to deal with that really
> 
> ... snip ...
>
> 2. Fix the kernel request_resource stuff to support a sleeping non
> exclusive resource so request/free of regions can be used as a resource
> semaphore by co-operative devices.
> 
> #2 is actually not hard but when I did the patch originally it then
> wasn't needed by the driver I had in mind for other reasons.
> 
> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
> 
> Maybe its worth resurrecting ?

In this particular case I most definitely think it's worth resurrecting.
Using your patch (I had to change the IORESOURCE_MUXED constant's value
though) I can completely solve the I/O sharing issue for the f71882fg +
watchdog case with only a single line modification to the f71882fg
driver.

One question regarding your patch though: how will it function when
driver (A) locks an I/O region using request_region() then driver (B)
comes along and tries to lock it using request_muxed_region()? One
problem I imagine might occur is that driver (A)'s 'struct resource'
doesn't have the IORESOURCE_MUXED flags set, thus simply won't wake up
driver (B) on the 'muxed_resource_wait' queue.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-25  8:54                       ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25  8:54 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1589 bytes --]

On Wed, Mar 24, 2010 at 03:51:51PM +0000, Alan Cox wrote:
>> hold on the SIO port range. This would thus interfere with the
>> operation of the f71882fg driver. I.e. it would prevent the device
>> probing stage from working, thus preventing it from loading *after*
>> my in-development watchdog driver.
> 
> There are two ways to deal with that really
> 
> ... snip ...
>
> 2. Fix the kernel request_resource stuff to support a sleeping non
> exclusive resource so request/free of regions can be used as a resource
> semaphore by co-operative devices.
> 
> #2 is actually not hard but when I did the patch originally it then
> wasn't needed by the driver I had in mind for other reasons.
> 
> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
> 
> Maybe its worth resurrecting ?

In this particular case I most definitely think it's worth resurrecting.
Using your patch (I had to change the IORESOURCE_MUXED constant's value
though) I can completely solve the I/O sharing issue for the f71882fg +
watchdog case with only a single line modification to the f71882fg
driver.

One question regarding your patch though: how will it function when
driver (A) locks an I/O region using request_region() then driver (B)
comes along and tries to lock it using request_muxed_region()? One
problem I imagine might occur is that driver (A)'s 'struct resource'
doesn't have the IORESOURCE_MUXED flags set, thus simply won't wake up
driver (B) on the 'muxed_resource_wait' queue.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-25  8:54                       ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
@ 2010-03-25 10:40                         ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 10:40 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4336 bytes --]

On Thu, Mar 25, 2010 at 09:54:50AM +0100, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 03:51:51PM +0000, Alan Cox wrote:
>>> hold on the SIO port range. This would thus interfere with the
>>> operation of the f71882fg driver. I.e. it would prevent the device
>>> probing stage from working, thus preventing it from loading *after*
>>> my in-development watchdog driver.
>> 
>> There are two ways to deal with that really
>> 
>> ... snip ...
>>
>> 2. Fix the kernel request_resource stuff to support a sleeping non
>> exclusive resource so request/free of regions can be used as a resource
>> semaphore by co-operative devices.
>> 
>> #2 is actually not hard but when I did the patch originally it then
>> wasn't needed by the driver I had in mind for other reasons.
>> 
>> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
>> 
>> Maybe its worth resurrecting ?
> 
> In this particular case I most definitely think it's worth resurrecting.
> Using your patch (I had to change the IORESOURCE_MUXED constant's value
> though) I can completely solve the I/O sharing issue for the f71882fg +
> watchdog case with only a single line modification to the f71882fg
> driver.
> 
> ... snip ...

Using Alan's patch and the one following the dashed line I can implement
(and have already done so) a separate watchdog driver for the Fintek
F71808E.

Should I just ask for this patch to be applied together with Alan's?
Then submit the new driver? (I'm a bit new to the non-technical aspects
of Linux kernel development).

========================================================================
hwmon: f71882fg: use a muxed resource lock for the Super I/O port

Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.
---
 drivers/hwmon/f71882fg.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7857ed3..e09416d 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2239,17 +2249,10 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
@@ -2306,7 +2309,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-25 10:40                         ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 10:40 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 4336 bytes --]

On Thu, Mar 25, 2010 at 09:54:50AM +0100, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 03:51:51PM +0000, Alan Cox wrote:
>>> hold on the SIO port range. This would thus interfere with the
>>> operation of the f71882fg driver. I.e. it would prevent the device
>>> probing stage from working, thus preventing it from loading *after*
>>> my in-development watchdog driver.
>> 
>> There are two ways to deal with that really
>> 
>> ... snip ...
>>
>> 2. Fix the kernel request_resource stuff to support a sleeping non
>> exclusive resource so request/free of regions can be used as a resource
>> semaphore by co-operative devices.
>> 
>> #2 is actually not hard but when I did the patch originally it then
>> wasn't needed by the driver I had in mind for other reasons.
>> 
>> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
>> 
>> Maybe its worth resurrecting ?
> 
> In this particular case I most definitely think it's worth resurrecting.
> Using your patch (I had to change the IORESOURCE_MUXED constant's value
> though) I can completely solve the I/O sharing issue for the f71882fg +
> watchdog case with only a single line modification to the f71882fg
> driver.
> 
> ... snip ...

Using Alan's patch and the one following the dashed line I can implement
(and have already done so) a separate watchdog driver for the Fintek
F71808E.

Should I just ask for this patch to be applied together with Alan's?
Then submit the new driver? (I'm a bit new to the non-technical aspects
of Linux kernel development).

========================================================================
hwmon: f71882fg: use a muxed resource lock for the Super I/O port

Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.
---
 drivers/hwmon/f71882fg.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7857ed3..e09416d 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2239,17 +2249,10 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
@@ -2306,7 +2309,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-25 10:40                         ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
@ 2010-03-25 12:50                           ` Alan Cox
  -1 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-25 12:50 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

O> Using Alan's patch and the one following the dashed line I can implement
> (and have already done so) a separate watchdog driver for the Fintek
> F71808E.
> 
> Should I just ask for this patch to be applied together with Alan's?
> Then submit the new driver? (I'm a bit new to the non-technical aspects
> of Linux kernel development).

I'd expect to see a submission of three patches I think

1. Patch adding the muxed resource support
2. Patch making the hwmon driver use it
3. Patch adding the new driver which needs it

and then we have a few other bits of code that probably should adopt it,
but that is a separate matter and other maintainers can do that bit.

Alan

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-25 12:50                           ` Alan Cox
  0 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-25 12:50 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

O> Using Alan's patch and the one following the dashed line I can implement
> (and have already done so) a separate watchdog driver for the Fintek
> F71808E.
> 
> Should I just ask for this patch to be applied together with Alan's?
> Then submit the new driver? (I'm a bit new to the non-technical aspects
> of Linux kernel development).

I'd expect to see a submission of three patches I think

1. Patch adding the muxed resource support
2. Patch making the hwmon driver use it
3. Patch adding the new driver which needs it

and then we have a few other bits of code that probably should adopt it,
but that is a separate matter and other maintainers can do that bit.

Alan

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889
  2010-03-25 12:50                           ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Alan Cox
@ 2010-03-25 13:06                             ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-25 13:06 UTC (permalink / raw)
  To: Alan Cox
  Cc: Giel van Schijndel, Jean Delvare, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Hi Giel,

On 03/25/2010 01:50 PM, Alan Cox wrote:
> O>  Using Alan's patch and the one following the dashed line I can implement
>> (and have already done so) a separate watchdog driver for the Fintek
>> F71808E.
>>
>> Should I just ask for this patch to be applied together with Alan's?
>> Then submit the new driver? (I'm a bit new to the non-technical aspects
>> of Linux kernel development).
>
> I'd expect to see a submission of three patches I think
>
> 1. Patch adding the muxed resource support
> 2. Patch making the hwmon driver use it
> 3. Patch adding the new driver which needs it
>
> and then we have a few other bits of code that probably should adopt it,
> but that is a separate matter and other maintainers can do that bit.
>

What Alan said :)

Although I'm not sure what the proper place is to post this entire set,
I guess linux-kernel itself, with lm_sensors in the CC.

Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-03-25 13:06                             ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-25 13:06 UTC (permalink / raw)
  To: Alan Cox
  Cc: Giel van Schijndel, Jean Delvare, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Hi Giel,

On 03/25/2010 01:50 PM, Alan Cox wrote:
> O>  Using Alan's patch and the one following the dashed line I can implement
>> (and have already done so) a separate watchdog driver for the Fintek
>> F71808E.
>>
>> Should I just ask for this patch to be applied together with Alan's?
>> Then submit the new driver? (I'm a bit new to the non-technical aspects
>> of Linux kernel development).
>
> I'd expect to see a submission of three patches I think
>
> 1. Patch adding the muxed resource support
> 2. Patch making the hwmon driver use it
> 3. Patch adding the new driver which needs it
>
> and then we have a few other bits of code that probably should adopt it,
> but that is a separate matter and other maintainers can do that bit.
>

What Alan said :)

Although I'm not sure what the proper place is to post this entire set,
I guess linux-kernel itself, with lm_sensors in the CC.

Regards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* [PATCH 1/3] resource: shared I/O region support
  2010-03-25 12:50                           ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Alan Cox
@ 2010-03-25 13:17                             ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 13:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel, Alan Cox

From: Alan Cox <alan@lxorguk.ukuu.org.uk>

This patch was originally written by Alan Cox [1]. I only updated it to
apply correctly to Linus' current tree and changed IORESOURCE_MUXED's
value from 0x00200000 to 0x00400000 because the former has already been
taken in use since.

[1] https://patchwork.kernel.org/patch/32397/

Patch after this line:
========================================================================
SuperIO devices share regions and use lock/unlock operations to chip
select.  We therefore need to be able to request a resource and wait for
it to be freed by whichever other SuperIO device currently hogs it.
Right now you have to poll which is horrible.

Add a MUXED field to IO port resources. If the MUXED field is set on the
resource and on the request (via request_muxed_region) then we block
until the previous owner of the muxed resource releases their region.

This allows us to implement proper resource sharing and locking for
superio chips using code of the form

enable_my_superio_dev() {
	request_muxed_region(0x44, 0x02, "superio:watchdog");
	outb() ..sequence to enable chip
}

disable_my_superio_dev() {
	outb() .. sequence of disable chip
	release_region(0x44, 0x02);
}

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 include/linux/ioport.h |    4 +++-
 kernel/resource.c      |   14 +++++++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 71ab79d..604fd29 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -52,6 +52,7 @@ struct resource_list {
 
 #define IORESOURCE_MEM_64	0x00100000
 #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
+#define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
 
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_DISABLED	0x10000000
@@ -141,7 +142,8 @@ static inline unsigned long resource_type(const struct resource *res)
 }
 
 /* Convenience shorthand with allocation */
-#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_region(start,n,name)		__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_muxed_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
 #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
 #define request_mem_region_exclusive(start,n,name) \
diff --git a/kernel/resource.c b/kernel/resource.c
index 2d5be5d..1484180 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -651,6 +651,8 @@ resource_size_t resource_alignment(struct resource *res)
  * release_region releases a matching busy region.
  */
 
+static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
+
 /**
  * __request_region - create a new busy resource region
  * @parent: parent resource descriptor
@@ -663,6 +665,7 @@ struct resource * __request_region(struct resource *parent,
 				   resource_size_t start, resource_size_t n,
 				   const char *name, int flags)
 {
+	DECLARE_WAITQUEUE(wait, current);
 	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (!res)
@@ -687,7 +690,14 @@ struct resource * __request_region(struct resource *parent,
 			if (!(conflict->flags & IORESOURCE_BUSY))
 				continue;
 		}
-
+		if (conflict->flags & flags & IORESOURCE_MUXED) {
+			add_wait_queue(&muxed_resource_wait, &wait);
+			write_unlock(&resource_lock);
+			schedule();
+			remove_wait_queue(&muxed_resource_wait, &wait);
+			write_lock(&resource_lock);
+			continue;
+		}
 		/* Uhhuh, that didn't work out.. */
 		kfree(res);
 		res = NULL;
@@ -761,6 +771,8 @@ void __release_region(struct resource *parent, resource_size_t start,
 				break;
 			*p = res->sibling;
 			write_unlock(&resource_lock);
+			if (res->flags & IORESOURCE_MUXED)
+				wake_up(&muxed_resource_wait);
 			kfree(res);
 			return;
 		}
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-25 13:17                             ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 13:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel, Alan Cox

From: Alan Cox <alan@lxorguk.ukuu.org.uk>

This patch was originally written by Alan Cox [1]. I only updated it to
apply correctly to Linus' current tree and changed IORESOURCE_MUXED's
value from 0x00200000 to 0x00400000 because the former has already been
taken in use since.

[1] https://patchwork.kernel.org/patch/32397/

Patch after this line:
====================================
SuperIO devices share regions and use lock/unlock operations to chip
select.  We therefore need to be able to request a resource and wait for
it to be freed by whichever other SuperIO device currently hogs it.
Right now you have to poll which is horrible.

Add a MUXED field to IO port resources. If the MUXED field is set on the
resource and on the request (via request_muxed_region) then we block
until the previous owner of the muxed resource releases their region.

This allows us to implement proper resource sharing and locking for
superio chips using code of the form

enable_my_superio_dev() {
	request_muxed_region(0x44, 0x02, "superio:watchdog");
	outb() ..sequence to enable chip
}

disable_my_superio_dev() {
	outb() .. sequence of disable chip
	release_region(0x44, 0x02);
}

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 include/linux/ioport.h |    4 +++-
 kernel/resource.c      |   14 +++++++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 71ab79d..604fd29 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -52,6 +52,7 @@ struct resource_list {
 
 #define IORESOURCE_MEM_64	0x00100000
 #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
+#define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
 
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_DISABLED	0x10000000
@@ -141,7 +142,8 @@ static inline unsigned long resource_type(const struct resource *res)
 }
 
 /* Convenience shorthand with allocation */
-#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_region(start,n,name)		__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_muxed_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
 #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
 #define request_mem_region_exclusive(start,n,name) \
diff --git a/kernel/resource.c b/kernel/resource.c
index 2d5be5d..1484180 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -651,6 +651,8 @@ resource_size_t resource_alignment(struct resource *res)
  * release_region releases a matching busy region.
  */
 
+static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
+
 /**
  * __request_region - create a new busy resource region
  * @parent: parent resource descriptor
@@ -663,6 +665,7 @@ struct resource * __request_region(struct resource *parent,
 				   resource_size_t start, resource_size_t n,
 				   const char *name, int flags)
 {
+	DECLARE_WAITQUEUE(wait, current);
 	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (!res)
@@ -687,7 +690,14 @@ struct resource * __request_region(struct resource *parent,
 			if (!(conflict->flags & IORESOURCE_BUSY))
 				continue;
 		}
-
+		if (conflict->flags & flags & IORESOURCE_MUXED) {
+			add_wait_queue(&muxed_resource_wait, &wait);
+			write_unlock(&resource_lock);
+			schedule();
+			remove_wait_queue(&muxed_resource_wait, &wait);
+			write_lock(&resource_lock);
+			continue;
+		}
 		/* Uhhuh, that didn't work out.. */
 		kfree(res);
 		res = NULL;
@@ -761,6 +771,8 @@ void __release_region(struct resource *parent, resource_size_t start,
 				break;
 			*p = res->sibling;
 			write_unlock(&resource_lock);
+			if (res->flags & IORESOURCE_MUXED)
+				wake_up(&muxed_resource_wait);
 			kfree(res);
 			return;
 		}
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-03-25 13:17                             ` [lm-sensors] " Giel van Schijndel
@ 2010-03-25 13:17                               ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 13:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7857ed3..e09416d 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2239,17 +2249,10 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
@@ -2306,7 +2309,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock
@ 2010-03-25 13:17                               ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 13:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7857ed3..e09416d 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2239,17 +2249,10 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
@@ -2306,7 +2309,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E
  2010-03-25 13:17                               ` [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock Giel van Schijndel
@ 2010-03-25 13:17                                 ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 13:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Add a new watchdog driver for the Fintek F71808E Super I/O chip.
---
 drivers/watchdog/Kconfig       |   11 +
 drivers/watchdog/Makefile      |    1 +
 drivers/watchdog/f71808e_wdt.c |  726 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 738 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/f71808e_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index bdcdbd5..653896f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -382,6 +382,17 @@ config ALIM7101_WDT
 
 	  Most people will say N.
 
+config F71808E_WDT
+	tristate "Fintek F71808E Watchdog"
+	depends on X86 && EXPERIMENTAL
+	help
+	  This is the driver for the hardware watchdog on the Fintek
+	  F71808E Super I/O chip.
+
+	  You can compile this driver directly into the kernel, or use
+	  it as a module.  The module will be called f71808e_wdt.
+
+
 config GEODE_WDT
 	tristate "AMD Geode CS5535/CS5536 Watchdog"
 	depends on CS5535_MFGPT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5e3cb95..e2f308d 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
 obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
+obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
 obj-$(CONFIG_GEODE_WDT) += geodewdt.o
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
 obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
new file mode 100644
index 0000000..7d547a9
--- /dev/null
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -0,0 +1,726 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
+ *   Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com>           *
+ *   Copyright (C) 2010 Giel van Schijndel <me@mortis.eu>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+
+#define DRVNAME "f71808e_wdt"
+
+#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
+#define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
+#define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
+
+#define SIO_REG_LDSEL		0x07	/* Logical device select */
+#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
+#define SIO_REG_DEVREV		0x22	/* Device revision */
+#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE		0x30	/* Logical device enable */
+#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
+#define SIO_F71858_ID		0x0507  /* Chipset ID */
+#define SIO_F71862_ID		0x0601	/* Chipset ID */
+#define SIO_F71882_ID		0x0541	/* Chipset ID */
+#define SIO_F71889_ID		0x0723	/* Chipset ID */
+
+#define	F71882FG_REG_START		0x01
+
+#define F71808FG_REG_WDO_CONF		0xf0
+#define F71808FG_REG_WDT_CONF		0xf5
+#define F71808FG_REG_WD_TIME		0xf6
+
+#define F71808FG_FLAG_WDOUT_EN		7
+
+#define F71808FG_FLAG_WDTMOUT_STS	5
+#define F71808FG_FLAG_WD_EN		5
+#define F71808FG_FLAG_WD_PULSE		4
+#define F71808FG_FLAG_WD_UNIT		3
+
+/* Default values */
+#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
+#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
+#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
+					   watchdog signal */
+
+static unsigned short force_id;
+module_param(force_id, ushort, 0);
+MODULE_PARM_DESC(force_id, "Override the detected device ID");
+
+static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
+static int timeout = 60;	/* default timeout in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in seconds. 1<= timeout <="
+			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
+			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
+module_param(pulse_width, uint, 0);
+MODULE_PARM_DESC(pulse_width,
+	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
+			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+static unsigned int start_withtimeout;
+module_param(start_withtimeout, uint, 0);
+MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
+	" given initial timeout. Zero (default) disables this feature.");
+
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg };
+
+static const char *f71808e_names[] = {
+	"f71808fg",
+	"f71858fg",
+	"f71862fg",
+	"f71882fg",
+	"f71889fg",
+};
+
+/* Super-I/O Function prototypes */
+static inline int superio_inb(int base, int reg);
+static inline int superio_inw(int base, int reg);
+static inline void superio_outb(int base, int reg, u8 val);
+static inline void superio_set_bit(int base, int reg, int bit);
+static inline void superio_clear_bit(int base, int reg, int bit);
+static inline int superio_enter(int base);
+static inline void superio_select(int base, int ld);
+static inline void superio_exit(int base);
+
+struct watchdog_data {
+	unsigned short	sioaddr;
+	enum chips	type;
+	unsigned long	opened;
+	struct mutex	lock;
+	char		expect_close;
+	struct watchdog_info ident;
+
+	unsigned short	timeout;
+	u8		timer_val;	/* content for the wd_time register */
+	char		minutes_mode;
+	u8		pulse_val;	/* pulse width flag */
+	char		pulse_mode;	/* enable pulse output mode? */
+	char		caused_reboot;	/* last reboot was by the watchdog */
+};
+
+static struct watchdog_data watchdog = {
+	.lock = __MUTEX_INITIALIZER(watchdog.lock),
+};
+
+/* Super I/O functions */
+static inline int superio_inb(int base, int reg)
+{
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static int superio_inw(int base, int reg)
+{
+	int val;
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
+	return val;
+}
+
+static inline void superio_outb(int base, int reg, u8 val)
+{
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static inline void superio_set_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__set_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__clear_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline int superio_enter(int base)
+{
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
+	/* according to the datasheet the key must be send twice! */
+	outb(SIO_UNLOCK_KEY, base);
+	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
+}
+
+static inline void superio_select(int base, int ld)
+{
+	outb(SIO_REG_LDSEL, base);
+	outb(ld, base + 1);
+}
+
+static inline void superio_exit(int base)
+{
+	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
+}
+
+static int watchdog_set_timeout(int timeout)
+{
+	if (timeout <= 0
+	 || timeout >  max_timeout) {
+		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&watchdog.lock);
+
+	watchdog.timeout = timeout;
+	if (timeout > 0xff) {
+		watchdog.timer_val = DIV_ROUND_UP(timeout, 60);
+		watchdog.minutes_mode = true;
+	} else {
+		watchdog.timer_val = timeout;
+		watchdog.minutes_mode = false;
+	}
+
+	mutex_unlock(&watchdog.lock);
+
+	return 0;
+}
+
+static int watchdog_set_pulse_width(unsigned int pw)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+
+	if        (pw <=    1) {
+		watchdog.pulse_val = 0;
+	} else if (pw <=   25) {
+		watchdog.pulse_val = 1;
+	} else if (pw <=  125) {
+		watchdog.pulse_val = 2;
+	} else if (pw <= 5000) {
+		watchdog.pulse_val = 3;
+	} else {
+		printk(KERN_ERR DRVNAME ": pulse width out of range\n");
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+
+	watchdog.pulse_mode = pw;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_keepalive(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+
+	if (watchdog.minutes_mode)
+		/* select minutes for timer units */
+		superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+	else
+		/* select seconds for timer units */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+
+	/* Set timer value */
+	superio_outb(watchdog.sioaddr, F71808FG_REG_WD_TIME,
+			   watchdog.timeout);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_start(void)
+{
+	/* Make sure we don't die as soon as the watchdog is enabled below */
+	int err = watchdog_keepalive();
+	if (err)
+		return err;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+
+	/* Watchdog pin configuration */
+	switch (watchdog.type) {
+	case f71808fg:
+		/* Set ping 21 to GPIO23/WDTRST#, then to WDTRST# */
+		superio_clear_bit(watchdog.sioaddr, 0x2a, 3);
+		superio_clear_bit(watchdog.sioaddr, 0x2b, 3);
+		break;
+
+	default:
+		/*
+		 * 'default' label to shut up the compiler and catch
+		 * programmer errors
+		 */
+		err = -ENODEV;
+		goto exit_superio;
+	}
+
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+	superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0);
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF,
+			F71808FG_FLAG_WDOUT_EN);
+
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	if (watchdog.pulse_mode) {
+		/* Select "pulse" output mode with given duration */
+		u8 wdt_conf = superio_inb(watchdog.sioaddr,
+				F71808FG_REG_WDT_CONF);
+
+		/* Set WD_PSWIDTH bits (1:0) */
+		wdt_conf = (wdt_conf & 0xfc) | (watchdog.pulse_val & 0x03);
+		/* Set WD_PULSE to "pulse" mode */
+		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
+
+		superio_outb(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				wdt_conf);
+	} else {
+		/* Select "level" output mode */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_PULSE);
+	}
+
+exit_superio:
+	superio_exit(watchdog.sioaddr);
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_stop(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+
+	superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_get_status(void)
+{
+	int status = 0;
+
+	mutex_lock(&watchdog.lock);
+	status = (watchdog.caused_reboot) ? WDIOF_CARDRESET : 0;
+	mutex_unlock(&watchdog.lock);
+
+	return status;
+}
+
+/* /dev/watchdog api */
+
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	int err;
+
+	/* If the watchdog is alive we don't need to start it again */
+	if (test_and_set_bit(0, &watchdog.opened))
+		return -EBUSY;
+
+	err = watchdog_start();
+	if (err) {
+		clear_bit(0, &watchdog.opened);
+		return err;
+	}
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	watchdog.expect_close = 0;
+	return nonseekable_open(inode, file);
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &watchdog.opened);
+
+	if (!watchdog.expect_close) {
+		watchdog_keepalive();
+		printk(KERN_CRIT DRVNAME
+			": Unexpected close, not stopping watchdog!\n");
+	} else if (!nowayout) {
+		watchdog_stop();
+	}
+	return 0;
+}
+
+/*
+ *      watchdog_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t watchdog_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			bool expect_close = false;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				expect_close = (c == 'V');
+			}
+
+			/* Properly order writes across fork()ed processes */
+			mutex_lock(&watchdog.lock);
+			watchdog.expect_close = expect_close;
+			mutex_unlock(&watchdog.lock);
+		}
+
+		/* someone wrote to us, we should restart timer */
+		watchdog_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      watchdog_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+static long watchdog_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	int status;
+	int new_options;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &watchdog.ident,
+			sizeof(watchdog.ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		status = watchdog_get_status();
+		if (status < 0)
+			return status;
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD)
+			watchdog_stop();
+
+		if (new_options & WDIOS_ENABLECARD)
+			return watchdog_start();
+
+
+	case WDIOC_KEEPALIVE:
+		watchdog_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (watchdog_set_timeout(new_timeout))
+			return -EINVAL;
+
+		watchdog_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(watchdog.timeout, uarg.i);
+
+	default:
+		return -ENOTTY;
+
+	}
+}
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		watchdog_stop();
+	return NOTIFY_DONE;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= watchdog_open,
+	.release	= watchdog_release,
+	.write		= watchdog_write,
+	.unlocked_ioctl	= watchdog_ioctl,
+};
+
+static struct miscdevice watchdog_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &watchdog_fops,
+};
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+static int __init watchdog_init(int sioaddr)
+{
+	int wdt_conf, err = 0;
+
+	/* No need to lock watchdog.lock here because no entry points
+	 * into the module have been registered yet.
+	 */
+	watchdog.sioaddr = sioaddr;
+	watchdog.ident.options = WDIOC_SETTIMEOUT
+				| WDIOF_MAGICCLOSE
+				| WDIOF_KEEPALIVEPING;
+
+	snprintf(watchdog.ident.identity,
+		sizeof(watchdog.ident.identity), "%s watchdog",
+		f71808e_names[watchdog.type]);
+
+	err = superio_enter(sioaddr);
+	if (err)
+		return err;
+
+	wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF);
+	watchdog.caused_reboot = wdt_conf & F71808FG_FLAG_WDTMOUT_STS;
+
+	superio_exit(sioaddr);
+
+	err = watchdog_set_timeout(timeout);
+	if (err)
+		return err;
+	err = watchdog_set_pulse_width(pulse_width);
+	if (err)
+		return err;
+
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err)
+		return err;
+
+	err = misc_register(&watchdog_miscdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME
+			": cannot register miscdev on minor=%d\n",
+				watchdog_miscdev.minor);
+		goto exit_reboot;
+	}
+
+	if (start_withtimeout) {
+		if (start_withtimeout <= 0
+		 || start_withtimeout >  max_timeout) {
+			printk(KERN_ERR DRVNAME
+				": starting timeout out of range\n");
+			err = -EINVAL;
+			goto exit_miscdev;
+		}
+
+		err = watchdog_start();
+		if (err) {
+			printk(KERN_ERR DRVNAME
+				": cannot start watchdog timer\n");
+			goto exit_miscdev;
+		}
+
+		mutex_lock(&watchdog.lock);
+		err = superio_enter(sioaddr);
+		if (err)
+			goto exit_unlock;
+
+		if (start_withtimeout > 0xff) {
+			/* select minutes for timer units */
+			superio_set_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				DIV_ROUND_UP(start_withtimeout, 60));
+		} else {
+			/* select seconds for timer units */
+			superio_clear_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				start_withtimeout);
+		}
+
+		superio_exit(sioaddr);
+		mutex_unlock(&watchdog.lock);
+
+		if (nowayout)
+			__module_get(THIS_MODULE);
+
+		printk(KERN_INFO DRVNAME
+			": watchdog started with initial timeout of %u sec\n",
+			start_withtimeout);
+	}
+
+	return 0;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+exit_miscdev:
+	misc_deregister(&watchdog_miscdev);
+exit_reboot:
+	unregister_reboot_notifier(&watchdog_notifier);
+
+	return err;
+}
+
+static int __init f71808e_find(int sioaddr)
+{
+	u16 devid;
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
+
+	devid = superio_inw(sioaddr, SIO_REG_MANID);
+	if (devid != SIO_FINTEK_ID) {
+		pr_debug(DRVNAME ": Not a Fintek device\n");
+		goto exit;
+	}
+
+	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
+	switch (devid) {
+	case SIO_F71808_ID:
+		watchdog.type = f71808fg;
+		break;
+	case SIO_F71862_ID:
+	case SIO_F71882_ID:
+	case SIO_F71889_ID:
+		/* These have a watchdog, though it isn't implemented (yet). */
+		err = -ENOSYS;
+		goto exit;
+	case SIO_F71858_ID:
+		/* Confirmed (by datasheet) not to have a watchdog. */
+		err = -ENODEV;
+		goto exit;
+	default:
+		printk(KERN_INFO DRVNAME ": Unrecognized Fintek device: %04x\n",
+		       (unsigned int)devid);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	printk(KERN_INFO DRVNAME ": Found %s watchdog chip, revision %d\n",
+		f71808e_names[watchdog.type],
+		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
+exit:
+	superio_exit(sioaddr);
+	return err;
+}
+
+static int __init f71808e_init(void)
+{
+	static const unsigned short addrs[] = { 0x2e, 0x4e };
+	int err = -ENODEV;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
+		err = f71808e_find(addrs[i]);
+		if (err == 0)
+			break;
+	}
+	if (i == ARRAY_SIZE(addrs))
+		return err;
+
+	return watchdog_init(addrs[i]);
+}
+
+static void __exit f71808e_exit(void)
+{
+	watchdog_stop();
+	misc_deregister(&watchdog_miscdev);
+	unregister_reboot_notifier(&watchdog_notifier);
+}
+
+MODULE_DESCRIPTION("F71808E Watchdog Driver");
+MODULE_AUTHOR("Giel van Schijndel <me@mortis.eu>");
+MODULE_LICENSE("GPL");
+
+module_init(f71808e_init);
+module_exit(f71808e_exit);
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog
@ 2010-03-25 13:17                                 ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 13:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Giel van Schijndel, Jonathan Cameron,
	Laurens Leemans, lm-sensors, linux-kernel

Add a new watchdog driver for the Fintek F71808E Super I/O chip.
---
 drivers/watchdog/Kconfig       |   11 +
 drivers/watchdog/Makefile      |    1 +
 drivers/watchdog/f71808e_wdt.c |  726 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 738 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/f71808e_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index bdcdbd5..653896f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -382,6 +382,17 @@ config ALIM7101_WDT
 
 	  Most people will say N.
 
+config F71808E_WDT
+	tristate "Fintek F71808E Watchdog"
+	depends on X86 && EXPERIMENTAL
+	help
+	  This is the driver for the hardware watchdog on the Fintek
+	  F71808E Super I/O chip.
+
+	  You can compile this driver directly into the kernel, or use
+	  it as a module.  The module will be called f71808e_wdt.
+
+
 config GEODE_WDT
 	tristate "AMD Geode CS5535/CS5536 Watchdog"
 	depends on CS5535_MFGPT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5e3cb95..e2f308d 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
 obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
+obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
 obj-$(CONFIG_GEODE_WDT) += geodewdt.o
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
 obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
new file mode 100644
index 0000000..7d547a9
--- /dev/null
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -0,0 +1,726 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
+ *   Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com>           *
+ *   Copyright (C) 2010 Giel van Schijndel <me@mortis.eu>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+
+#define DRVNAME "f71808e_wdt"
+
+#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
+#define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
+#define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
+
+#define SIO_REG_LDSEL		0x07	/* Logical device select */
+#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
+#define SIO_REG_DEVREV		0x22	/* Device revision */
+#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE		0x30	/* Logical device enable */
+#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
+#define SIO_F71858_ID		0x0507  /* Chipset ID */
+#define SIO_F71862_ID		0x0601	/* Chipset ID */
+#define SIO_F71882_ID		0x0541	/* Chipset ID */
+#define SIO_F71889_ID		0x0723	/* Chipset ID */
+
+#define	F71882FG_REG_START		0x01
+
+#define F71808FG_REG_WDO_CONF		0xf0
+#define F71808FG_REG_WDT_CONF		0xf5
+#define F71808FG_REG_WD_TIME		0xf6
+
+#define F71808FG_FLAG_WDOUT_EN		7
+
+#define F71808FG_FLAG_WDTMOUT_STS	5
+#define F71808FG_FLAG_WD_EN		5
+#define F71808FG_FLAG_WD_PULSE		4
+#define F71808FG_FLAG_WD_UNIT		3
+
+/* Default values */
+#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
+#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
+#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
+					   watchdog signal */
+
+static unsigned short force_id;
+module_param(force_id, ushort, 0);
+MODULE_PARM_DESC(force_id, "Override the detected device ID");
+
+static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
+static int timeout = 60;	/* default timeout in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in seconds. 1<= timeout <="
+			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
+			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
+module_param(pulse_width, uint, 0);
+MODULE_PARM_DESC(pulse_width,
+	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
+			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+static unsigned int start_withtimeout;
+module_param(start_withtimeout, uint, 0);
+MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
+	" given initial timeout. Zero (default) disables this feature.");
+
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg };
+
+static const char *f71808e_names[] = {
+	"f71808fg",
+	"f71858fg",
+	"f71862fg",
+	"f71882fg",
+	"f71889fg",
+};
+
+/* Super-I/O Function prototypes */
+static inline int superio_inb(int base, int reg);
+static inline int superio_inw(int base, int reg);
+static inline void superio_outb(int base, int reg, u8 val);
+static inline void superio_set_bit(int base, int reg, int bit);
+static inline void superio_clear_bit(int base, int reg, int bit);
+static inline int superio_enter(int base);
+static inline void superio_select(int base, int ld);
+static inline void superio_exit(int base);
+
+struct watchdog_data {
+	unsigned short	sioaddr;
+	enum chips	type;
+	unsigned long	opened;
+	struct mutex	lock;
+	char		expect_close;
+	struct watchdog_info ident;
+
+	unsigned short	timeout;
+	u8		timer_val;	/* content for the wd_time register */
+	char		minutes_mode;
+	u8		pulse_val;	/* pulse width flag */
+	char		pulse_mode;	/* enable pulse output mode? */
+	char		caused_reboot;	/* last reboot was by the watchdog */
+};
+
+static struct watchdog_data watchdog = {
+	.lock = __MUTEX_INITIALIZER(watchdog.lock),
+};
+
+/* Super I/O functions */
+static inline int superio_inb(int base, int reg)
+{
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static int superio_inw(int base, int reg)
+{
+	int val;
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
+	return val;
+}
+
+static inline void superio_outb(int base, int reg, u8 val)
+{
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static inline void superio_set_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__set_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__clear_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline int superio_enter(int base)
+{
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
+	/* according to the datasheet the key must be send twice! */
+	outb(SIO_UNLOCK_KEY, base);
+	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
+}
+
+static inline void superio_select(int base, int ld)
+{
+	outb(SIO_REG_LDSEL, base);
+	outb(ld, base + 1);
+}
+
+static inline void superio_exit(int base)
+{
+	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
+}
+
+static int watchdog_set_timeout(int timeout)
+{
+	if (timeout <= 0
+	 || timeout >  max_timeout) {
+		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&watchdog.lock);
+
+	watchdog.timeout = timeout;
+	if (timeout > 0xff) {
+		watchdog.timer_val = DIV_ROUND_UP(timeout, 60);
+		watchdog.minutes_mode = true;
+	} else {
+		watchdog.timer_val = timeout;
+		watchdog.minutes_mode = false;
+	}
+
+	mutex_unlock(&watchdog.lock);
+
+	return 0;
+}
+
+static int watchdog_set_pulse_width(unsigned int pw)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+
+	if        (pw <=    1) {
+		watchdog.pulse_val = 0;
+	} else if (pw <=   25) {
+		watchdog.pulse_val = 1;
+	} else if (pw <=  125) {
+		watchdog.pulse_val = 2;
+	} else if (pw <= 5000) {
+		watchdog.pulse_val = 3;
+	} else {
+		printk(KERN_ERR DRVNAME ": pulse width out of range\n");
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+
+	watchdog.pulse_mode = pw;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_keepalive(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+
+	if (watchdog.minutes_mode)
+		/* select minutes for timer units */
+		superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+	else
+		/* select seconds for timer units */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+
+	/* Set timer value */
+	superio_outb(watchdog.sioaddr, F71808FG_REG_WD_TIME,
+			   watchdog.timeout);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_start(void)
+{
+	/* Make sure we don't die as soon as the watchdog is enabled below */
+	int err = watchdog_keepalive();
+	if (err)
+		return err;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+
+	/* Watchdog pin configuration */
+	switch (watchdog.type) {
+	case f71808fg:
+		/* Set ping 21 to GPIO23/WDTRST#, then to WDTRST# */
+		superio_clear_bit(watchdog.sioaddr, 0x2a, 3);
+		superio_clear_bit(watchdog.sioaddr, 0x2b, 3);
+		break;
+
+	default:
+		/*
+		 * 'default' label to shut up the compiler and catch
+		 * programmer errors
+		 */
+		err = -ENODEV;
+		goto exit_superio;
+	}
+
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+	superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0);
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF,
+			F71808FG_FLAG_WDOUT_EN);
+
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	if (watchdog.pulse_mode) {
+		/* Select "pulse" output mode with given duration */
+		u8 wdt_conf = superio_inb(watchdog.sioaddr,
+				F71808FG_REG_WDT_CONF);
+
+		/* Set WD_PSWIDTH bits (1:0) */
+		wdt_conf = (wdt_conf & 0xfc) | (watchdog.pulse_val & 0x03);
+		/* Set WD_PULSE to "pulse" mode */
+		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
+
+		superio_outb(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				wdt_conf);
+	} else {
+		/* Select "level" output mode */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_PULSE);
+	}
+
+exit_superio:
+	superio_exit(watchdog.sioaddr);
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_stop(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+
+	superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_get_status(void)
+{
+	int status = 0;
+
+	mutex_lock(&watchdog.lock);
+	status = (watchdog.caused_reboot) ? WDIOF_CARDRESET : 0;
+	mutex_unlock(&watchdog.lock);
+
+	return status;
+}
+
+/* /dev/watchdog api */
+
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	int err;
+
+	/* If the watchdog is alive we don't need to start it again */
+	if (test_and_set_bit(0, &watchdog.opened))
+		return -EBUSY;
+
+	err = watchdog_start();
+	if (err) {
+		clear_bit(0, &watchdog.opened);
+		return err;
+	}
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	watchdog.expect_close = 0;
+	return nonseekable_open(inode, file);
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &watchdog.opened);
+
+	if (!watchdog.expect_close) {
+		watchdog_keepalive();
+		printk(KERN_CRIT DRVNAME
+			": Unexpected close, not stopping watchdog!\n");
+	} else if (!nowayout) {
+		watchdog_stop();
+	}
+	return 0;
+}
+
+/*
+ *      watchdog_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t watchdog_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			bool expect_close = false;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				expect_close = (c = 'V');
+			}
+
+			/* Properly order writes across fork()ed processes */
+			mutex_lock(&watchdog.lock);
+			watchdog.expect_close = expect_close;
+			mutex_unlock(&watchdog.lock);
+		}
+
+		/* someone wrote to us, we should restart timer */
+		watchdog_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      watchdog_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+static long watchdog_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	int status;
+	int new_options;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &watchdog.ident,
+			sizeof(watchdog.ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		status = watchdog_get_status();
+		if (status < 0)
+			return status;
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD)
+			watchdog_stop();
+
+		if (new_options & WDIOS_ENABLECARD)
+			return watchdog_start();
+
+
+	case WDIOC_KEEPALIVE:
+		watchdog_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (watchdog_set_timeout(new_timeout))
+			return -EINVAL;
+
+		watchdog_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(watchdog.timeout, uarg.i);
+
+	default:
+		return -ENOTTY;
+
+	}
+}
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code = SYS_DOWN || code = SYS_HALT)
+		watchdog_stop();
+	return NOTIFY_DONE;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= watchdog_open,
+	.release	= watchdog_release,
+	.write		= watchdog_write,
+	.unlocked_ioctl	= watchdog_ioctl,
+};
+
+static struct miscdevice watchdog_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &watchdog_fops,
+};
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+static int __init watchdog_init(int sioaddr)
+{
+	int wdt_conf, err = 0;
+
+	/* No need to lock watchdog.lock here because no entry points
+	 * into the module have been registered yet.
+	 */
+	watchdog.sioaddr = sioaddr;
+	watchdog.ident.options = WDIOC_SETTIMEOUT
+				| WDIOF_MAGICCLOSE
+				| WDIOF_KEEPALIVEPING;
+
+	snprintf(watchdog.ident.identity,
+		sizeof(watchdog.ident.identity), "%s watchdog",
+		f71808e_names[watchdog.type]);
+
+	err = superio_enter(sioaddr);
+	if (err)
+		return err;
+
+	wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF);
+	watchdog.caused_reboot = wdt_conf & F71808FG_FLAG_WDTMOUT_STS;
+
+	superio_exit(sioaddr);
+
+	err = watchdog_set_timeout(timeout);
+	if (err)
+		return err;
+	err = watchdog_set_pulse_width(pulse_width);
+	if (err)
+		return err;
+
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err)
+		return err;
+
+	err = misc_register(&watchdog_miscdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME
+			": cannot register miscdev on minor=%d\n",
+				watchdog_miscdev.minor);
+		goto exit_reboot;
+	}
+
+	if (start_withtimeout) {
+		if (start_withtimeout <= 0
+		 || start_withtimeout >  max_timeout) {
+			printk(KERN_ERR DRVNAME
+				": starting timeout out of range\n");
+			err = -EINVAL;
+			goto exit_miscdev;
+		}
+
+		err = watchdog_start();
+		if (err) {
+			printk(KERN_ERR DRVNAME
+				": cannot start watchdog timer\n");
+			goto exit_miscdev;
+		}
+
+		mutex_lock(&watchdog.lock);
+		err = superio_enter(sioaddr);
+		if (err)
+			goto exit_unlock;
+
+		if (start_withtimeout > 0xff) {
+			/* select minutes for timer units */
+			superio_set_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				DIV_ROUND_UP(start_withtimeout, 60));
+		} else {
+			/* select seconds for timer units */
+			superio_clear_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				start_withtimeout);
+		}
+
+		superio_exit(sioaddr);
+		mutex_unlock(&watchdog.lock);
+
+		if (nowayout)
+			__module_get(THIS_MODULE);
+
+		printk(KERN_INFO DRVNAME
+			": watchdog started with initial timeout of %u sec\n",
+			start_withtimeout);
+	}
+
+	return 0;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+exit_miscdev:
+	misc_deregister(&watchdog_miscdev);
+exit_reboot:
+	unregister_reboot_notifier(&watchdog_notifier);
+
+	return err;
+}
+
+static int __init f71808e_find(int sioaddr)
+{
+	u16 devid;
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
+
+	devid = superio_inw(sioaddr, SIO_REG_MANID);
+	if (devid != SIO_FINTEK_ID) {
+		pr_debug(DRVNAME ": Not a Fintek device\n");
+		goto exit;
+	}
+
+	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
+	switch (devid) {
+	case SIO_F71808_ID:
+		watchdog.type = f71808fg;
+		break;
+	case SIO_F71862_ID:
+	case SIO_F71882_ID:
+	case SIO_F71889_ID:
+		/* These have a watchdog, though it isn't implemented (yet). */
+		err = -ENOSYS;
+		goto exit;
+	case SIO_F71858_ID:
+		/* Confirmed (by datasheet) not to have a watchdog. */
+		err = -ENODEV;
+		goto exit;
+	default:
+		printk(KERN_INFO DRVNAME ": Unrecognized Fintek device: %04x\n",
+		       (unsigned int)devid);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	printk(KERN_INFO DRVNAME ": Found %s watchdog chip, revision %d\n",
+		f71808e_names[watchdog.type],
+		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
+exit:
+	superio_exit(sioaddr);
+	return err;
+}
+
+static int __init f71808e_init(void)
+{
+	static const unsigned short addrs[] = { 0x2e, 0x4e };
+	int err = -ENODEV;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
+		err = f71808e_find(addrs[i]);
+		if (err = 0)
+			break;
+	}
+	if (i = ARRAY_SIZE(addrs))
+		return err;
+
+	return watchdog_init(addrs[i]);
+}
+
+static void __exit f71808e_exit(void)
+{
+	watchdog_stop();
+	misc_deregister(&watchdog_miscdev);
+	unregister_reboot_notifier(&watchdog_notifier);
+}
+
+MODULE_DESCRIPTION("F71808E Watchdog Driver");
+MODULE_AUTHOR("Giel van Schijndel <me@mortis.eu>");
+MODULE_LICENSE("GPL");
+
+module_init(f71808e_init);
+module_exit(f71808e_exit);
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-25 13:17                             ` [lm-sensors] " Giel van Schijndel
@ 2010-03-25 15:57                               ` Alan Cox
  -1 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-25 15:57 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

On Thu, 25 Mar 2010 14:17:41 +0100
Giel van Schijndel <me@mortis.eu> wrote:

> From: Alan Cox <alan@lxorguk.ukuu.org.uk>
> 
> This patch was originally written by Alan Cox [1]. I only updated it to
> apply correctly to Linus' current tree and changed IORESOURCE_MUXED's
> value from 0x00200000 to 0x00400000 because the former has already been
> taken in use since.
> 
> [1] https://patchwork.kernel.org/patch/32397/
> 
> Patch after this line:
> ========================================================================
> SuperIO devices share regions and use lock/unlock operations to chip
> select.  We therefore need to be able to request a resource and wait for
> it to be freed by whichever other SuperIO device currently hogs it.
> Right now you have to poll which is horrible.
> 
> Add a MUXED field to IO port resources. If the MUXED field is set on the
> resource and on the request (via request_muxed_region) then we block
> until the previous owner of the muxed resource releases their region.
> 
> This allows us to implement proper resource sharing and locking for
> superio chips using code of the form
> 
> enable_my_superio_dev() {
> 	request_muxed_region(0x44, 0x02, "superio:watchdog");
> 	outb() ..sequence to enable chip
> }
> 
> disable_my_superio_dev() {
> 	outb() .. sequence of disable chip
> 	release_region(0x44, 0x02);
> }
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>
> ---
>  include/linux/ioport.h |    4 +++-
>  kernel/resource.c      |   14 +++++++++++++-
>  2 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/ioport.h b/include/linux/ioport.h
> index 71ab79d..604fd29 100644
> --- a/include/linux/ioport.h
> +++ b/include/linux/ioport.h
> @@ -52,6 +52,7 @@ struct resource_list {
>  
>  #define IORESOURCE_MEM_64	0x00100000
>  #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
> +#define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
>  
>  #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
>  #define IORESOURCE_DISABLED	0x10000000
> @@ -141,7 +142,8 @@ static inline unsigned long resource_type(const struct resource *res)
>  }
>  
>  /* Convenience shorthand with allocation */
> -#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
> +#define request_region(start,n,name)		__request_region(&ioport_resource, (start), (n), (name), 0)
> +#define request_muxed_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
>  #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
>  #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
>  #define request_mem_region_exclusive(start,n,name) \
> diff --git a/kernel/resource.c b/kernel/resource.c
> index 2d5be5d..1484180 100644
> --- a/kernel/resource.c
> +++ b/kernel/resource.c
> @@ -651,6 +651,8 @@ resource_size_t resource_alignment(struct resource *res)
>   * release_region releases a matching busy region.
>   */
>  
> +static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
> +
>  /**
>   * __request_region - create a new busy resource region
>   * @parent: parent resource descriptor
> @@ -663,6 +665,7 @@ struct resource * __request_region(struct resource *parent,
>  				   resource_size_t start, resource_size_t n,
>  				   const char *name, int flags)
>  {
> +	DECLARE_WAITQUEUE(wait, current);
>  	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
>  
>  	if (!res)
> @@ -687,7 +690,14 @@ struct resource * __request_region(struct resource *parent,
>  			if (!(conflict->flags & IORESOURCE_BUSY))
>  				continue;
>  		}
> -
> +		if (conflict->flags & flags & IORESOURCE_MUXED) {
> +			add_wait_queue(&muxed_resource_wait, &wait);
> +			write_unlock(&resource_lock);

needs a set_current_state(TASK_UNINTERRUPTIBLE); here

(error from my original test patch that I noticed re-reviewing it)



^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-25 15:57                               ` Alan Cox
  0 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-25 15:57 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

On Thu, 25 Mar 2010 14:17:41 +0100
Giel van Schijndel <me@mortis.eu> wrote:

> From: Alan Cox <alan@lxorguk.ukuu.org.uk>
> 
> This patch was originally written by Alan Cox [1]. I only updated it to
> apply correctly to Linus' current tree and changed IORESOURCE_MUXED's
> value from 0x00200000 to 0x00400000 because the former has already been
> taken in use since.
> 
> [1] https://patchwork.kernel.org/patch/32397/
> 
> Patch after this line:
> ====================================
> SuperIO devices share regions and use lock/unlock operations to chip
> select.  We therefore need to be able to request a resource and wait for
> it to be freed by whichever other SuperIO device currently hogs it.
> Right now you have to poll which is horrible.
> 
> Add a MUXED field to IO port resources. If the MUXED field is set on the
> resource and on the request (via request_muxed_region) then we block
> until the previous owner of the muxed resource releases their region.
> 
> This allows us to implement proper resource sharing and locking for
> superio chips using code of the form
> 
> enable_my_superio_dev() {
> 	request_muxed_region(0x44, 0x02, "superio:watchdog");
> 	outb() ..sequence to enable chip
> }
> 
> disable_my_superio_dev() {
> 	outb() .. sequence of disable chip
> 	release_region(0x44, 0x02);
> }
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>
> ---
>  include/linux/ioport.h |    4 +++-
>  kernel/resource.c      |   14 +++++++++++++-
>  2 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/ioport.h b/include/linux/ioport.h
> index 71ab79d..604fd29 100644
> --- a/include/linux/ioport.h
> +++ b/include/linux/ioport.h
> @@ -52,6 +52,7 @@ struct resource_list {
>  
>  #define IORESOURCE_MEM_64	0x00100000
>  #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
> +#define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
>  
>  #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
>  #define IORESOURCE_DISABLED	0x10000000
> @@ -141,7 +142,8 @@ static inline unsigned long resource_type(const struct resource *res)
>  }
>  
>  /* Convenience shorthand with allocation */
> -#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
> +#define request_region(start,n,name)		__request_region(&ioport_resource, (start), (n), (name), 0)
> +#define request_muxed_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
>  #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
>  #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
>  #define request_mem_region_exclusive(start,n,name) \
> diff --git a/kernel/resource.c b/kernel/resource.c
> index 2d5be5d..1484180 100644
> --- a/kernel/resource.c
> +++ b/kernel/resource.c
> @@ -651,6 +651,8 @@ resource_size_t resource_alignment(struct resource *res)
>   * release_region releases a matching busy region.
>   */
>  
> +static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
> +
>  /**
>   * __request_region - create a new busy resource region
>   * @parent: parent resource descriptor
> @@ -663,6 +665,7 @@ struct resource * __request_region(struct resource *parent,
>  				   resource_size_t start, resource_size_t n,
>  				   const char *name, int flags)
>  {
> +	DECLARE_WAITQUEUE(wait, current);
>  	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
>  
>  	if (!res)
> @@ -687,7 +690,14 @@ struct resource * __request_region(struct resource *parent,
>  			if (!(conflict->flags & IORESOURCE_BUSY))
>  				continue;
>  		}
> -
> +		if (conflict->flags & flags & IORESOURCE_MUXED) {
> +			add_wait_queue(&muxed_resource_wait, &wait);
> +			write_unlock(&resource_lock);

needs a set_current_state(TASK_UNINTERRUPTIBLE); here

(error from my original test patch that I noticed re-reviewing it)



_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-25 15:57                               ` [lm-sensors] " Alan Cox
@ 2010-03-25 18:03                                 ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 18:03 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5477 bytes --]

On Thu, Mar 25, 2010 at 03:57:05PM +0000, Alan Cox wrote:
> On Thu, 25 Mar 2010 14:17:41 +0100 Giel van Schijndel wrote:
>> From: Alan Cox <alan@lxorguk.ukuu.org.uk>
>> 
>> This patch was originally written by Alan Cox [1]. I only updated it to
>> apply correctly to Linus' current tree and changed IORESOURCE_MUXED's
>> value from 0x00200000 to 0x00400000 because the former has already been
>> taken in use since.
>> 
>> [1] https://patchwork.kernel.org/patch/32397/
>> 
>> Patch after this line:
>> ========================================================================
>> ... snip ...
>> @@ -687,7 +690,14 @@ struct resource * __request_region(struct resource *parent,
>>  			if (!(conflict->flags & IORESOURCE_BUSY))
>>  				continue;
>>  		}
>> -
>> +		if (conflict->flags & flags & IORESOURCE_MUXED) {
>> +			add_wait_queue(&muxed_resource_wait, &wait);
>> +			write_unlock(&resource_lock);
> 
> needs a set_current_state(TASK_UNINTERRUPTIBLE); here
> 
> (error from my original test patch that I noticed re-reviewing it)

Always fun reviewing your own code ;-)

New patch attached.

One question though. I did some reading in
Documentation/memory-barriers.txt and think it is correct *not* to call
set_current_state(TASK_INTERRUPTIBLE) after schedule() finishes. Could
you confirm or deny that?

Patch after this line:
resource: shared I/O region support

SuperIO devices share regions and use lock/unlock operations to chip
select.  We therefore need to be able to request a resource and wait for
it to be freed by whichever other SuperIO device currently hogs it.
Right now you have to poll which is horrible.

Add a MUXED field to IO port resources. If the MUXED field is set on the
resource and on the request (via request_muxed_region) then we block
until the previous owner of the muxed resource releases their region.

This allows us to implement proper resource sharing and locking for
superio chips using code of the form

enable_my_superio_dev() {
	request_muxed_region(0x44, 0x02, "superio:watchdog");
	outb() ..sequence to enable chip
}

disable_my_superio_dev() {
	outb() .. sequence of disable chip
	release_region(0x44, 0x02);
}

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 include/linux/ioport.h |    4 +++-
 kernel/resource.c      |   16 +++++++++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 71ab79d..604fd29 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -52,6 +52,7 @@ struct resource_list {
 
 #define IORESOURCE_MEM_64	0x00100000
 #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
+#define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
 
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_DISABLED	0x10000000
@@ -141,7 +142,8 @@ static inline unsigned long resource_type(const struct resource *res)
 }
 
 /* Convenience shorthand with allocation */
-#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_region(start,n,name)		__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_muxed_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
 #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
 #define request_mem_region_exclusive(start,n,name) \
diff --git a/kernel/resource.c b/kernel/resource.c
index 2d5be5d..ab44c7f 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -15,6 +15,7 @@
 #include <linux/spinlock.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/pfn.h>
@@ -651,6 +652,8 @@ resource_size_t resource_alignment(struct resource *res)
  * release_region releases a matching busy region.
  */
 
+static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
+
 /**
  * __request_region - create a new busy resource region
  * @parent: parent resource descriptor
@@ -663,6 +666,7 @@ struct resource * __request_region(struct resource *parent,
 				   resource_size_t start, resource_size_t n,
 				   const char *name, int flags)
 {
+	DECLARE_WAITQUEUE(wait, current);
 	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (!res)
@@ -687,7 +691,15 @@ struct resource * __request_region(struct resource *parent,
 			if (!(conflict->flags & IORESOURCE_BUSY))
 				continue;
 		}
-
+		if (conflict->flags & flags & IORESOURCE_MUXED) {
+			add_wait_queue(&muxed_resource_wait, &wait);
+			write_unlock(&resource_lock);
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule();
+			remove_wait_queue(&muxed_resource_wait, &wait);
+			write_lock(&resource_lock);
+			continue;
+		}
 		/* Uhhuh, that didn't work out.. */
 		kfree(res);
 		res = NULL;
@@ -761,6 +773,8 @@ void __release_region(struct resource *parent, resource_size_t start,
 				break;
 			*p = res->sibling;
 			write_unlock(&resource_lock);
+			if (res->flags & IORESOURCE_MUXED)
+				wake_up(&muxed_resource_wait);
 			kfree(res);
 			return;
 		}
-- 
1.6.4.4

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-25 18:03                                 ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-25 18:03 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 5477 bytes --]

On Thu, Mar 25, 2010 at 03:57:05PM +0000, Alan Cox wrote:
> On Thu, 25 Mar 2010 14:17:41 +0100 Giel van Schijndel wrote:
>> From: Alan Cox <alan@lxorguk.ukuu.org.uk>
>> 
>> This patch was originally written by Alan Cox [1]. I only updated it to
>> apply correctly to Linus' current tree and changed IORESOURCE_MUXED's
>> value from 0x00200000 to 0x00400000 because the former has already been
>> taken in use since.
>> 
>> [1] https://patchwork.kernel.org/patch/32397/
>> 
>> Patch after this line:
>> ========================================================================
>> ... snip ...
>> @@ -687,7 +690,14 @@ struct resource * __request_region(struct resource *parent,
>>  			if (!(conflict->flags & IORESOURCE_BUSY))
>>  				continue;
>>  		}
>> -
>> +		if (conflict->flags & flags & IORESOURCE_MUXED) {
>> +			add_wait_queue(&muxed_resource_wait, &wait);
>> +			write_unlock(&resource_lock);
> 
> needs a set_current_state(TASK_UNINTERRUPTIBLE); here
> 
> (error from my original test patch that I noticed re-reviewing it)

Always fun reviewing your own code ;-)

New patch attached.

One question though. I did some reading in
Documentation/memory-barriers.txt and think it is correct *not* to call
set_current_state(TASK_INTERRUPTIBLE) after schedule() finishes. Could
you confirm or deny that?

Patch after this line:
resource: shared I/O region support

SuperIO devices share regions and use lock/unlock operations to chip
select.  We therefore need to be able to request a resource and wait for
it to be freed by whichever other SuperIO device currently hogs it.
Right now you have to poll which is horrible.

Add a MUXED field to IO port resources. If the MUXED field is set on the
resource and on the request (via request_muxed_region) then we block
until the previous owner of the muxed resource releases their region.

This allows us to implement proper resource sharing and locking for
superio chips using code of the form

enable_my_superio_dev() {
	request_muxed_region(0x44, 0x02, "superio:watchdog");
	outb() ..sequence to enable chip
}

disable_my_superio_dev() {
	outb() .. sequence of disable chip
	release_region(0x44, 0x02);
}

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 include/linux/ioport.h |    4 +++-
 kernel/resource.c      |   16 +++++++++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 71ab79d..604fd29 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -52,6 +52,7 @@ struct resource_list {
 
 #define IORESOURCE_MEM_64	0x00100000
 #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
+#define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
 
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_DISABLED	0x10000000
@@ -141,7 +142,8 @@ static inline unsigned long resource_type(const struct resource *res)
 }
 
 /* Convenience shorthand with allocation */
-#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_region(start,n,name)		__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_muxed_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
 #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
 #define request_mem_region_exclusive(start,n,name) \
diff --git a/kernel/resource.c b/kernel/resource.c
index 2d5be5d..ab44c7f 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -15,6 +15,7 @@
 #include <linux/spinlock.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/pfn.h>
@@ -651,6 +652,8 @@ resource_size_t resource_alignment(struct resource *res)
  * release_region releases a matching busy region.
  */
 
+static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
+
 /**
  * __request_region - create a new busy resource region
  * @parent: parent resource descriptor
@@ -663,6 +666,7 @@ struct resource * __request_region(struct resource *parent,
 				   resource_size_t start, resource_size_t n,
 				   const char *name, int flags)
 {
+	DECLARE_WAITQUEUE(wait, current);
 	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (!res)
@@ -687,7 +691,15 @@ struct resource * __request_region(struct resource *parent,
 			if (!(conflict->flags & IORESOURCE_BUSY))
 				continue;
 		}
-
+		if (conflict->flags & flags & IORESOURCE_MUXED) {
+			add_wait_queue(&muxed_resource_wait, &wait);
+			write_unlock(&resource_lock);
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule();
+			remove_wait_queue(&muxed_resource_wait, &wait);
+			write_lock(&resource_lock);
+			continue;
+		}
 		/* Uhhuh, that didn't work out.. */
 		kfree(res);
 		res = NULL;
@@ -761,6 +773,8 @@ void __release_region(struct resource *parent, resource_size_t start,
 				break;
 			*p = res->sibling;
 			write_unlock(&resource_lock);
+			if (res->flags & IORESOURCE_MUXED)
+				wake_up(&muxed_resource_wait);
 			kfree(res);
 			return;
 		}
-- 
1.6.4.4

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-25 18:03                                 ` [lm-sensors] " Giel van Schijndel
@ 2010-03-25 18:16                                   ` Alan Cox
  -1 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-25 18:16 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

> Always fun reviewing your own code ;-)
> 
> New patch attached.
> 
> One question though. I did some reading in
> Documentation/memory-barriers.txt and think it is correct *not* to call
> set_current_state(TASK_INTERRUPTIBLE) after schedule() finishes. Could
> you confirm or deny that?

After the schedule() returns we will be in TASK_RUNNING which is where we
want to be ...


> +			if (res->flags & IORESOURCE_MUXED)
> +				wake_up(&muxed_resource_wait);
>  			kfree(res);
>  			return;

And you'll want a

Signed-off-by: Alan Cox <alan@linux.intel.com>


>  		}


-- 
--
	"Alan, I'm getting a bit worried about you."
				-- Linus Torvalds

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-25 18:16                                   ` Alan Cox
  0 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-25 18:16 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

> Always fun reviewing your own code ;-)
> 
> New patch attached.
> 
> One question though. I did some reading in
> Documentation/memory-barriers.txt and think it is correct *not* to call
> set_current_state(TASK_INTERRUPTIBLE) after schedule() finishes. Could
> you confirm or deny that?

After the schedule() returns we will be in TASK_RUNNING which is where we
want to be ...


> +			if (res->flags & IORESOURCE_MUXED)
> +				wake_up(&muxed_resource_wait);
>  			kfree(res);
>  			return;

And you'll want a

Signed-off-by: Alan Cox <alan@linux.intel.com>


>  		}


-- 
--
	"Alan, I'm getting a bit worried about you."
				-- Linus Torvalds

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-03-25 13:17                               ` [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock Giel van Schijndel
@ 2010-03-25 21:10                                 ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-25 21:10 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

On 03/25/2010 02:17 PM, Giel van Schijndel wrote:
> Sleep while acquiring a resource lock on the Super I/O port. This should
> prevent collisions from causing the hardware probe to fail with -EBUSY.
>

Looks good to me (assuming the previous patch in the series gets applied).
Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

hans

> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |   28 +++++++++++++++-------------
>   1 files changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 7857ed3..e09416d 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
>   /* Super-I/O Function prototypes */
>   static inline int superio_inb(int base, int reg);
>   static inline int superio_inw(int base, int reg);
> -static inline void superio_enter(int base);
> +static inline int superio_enter(int base);
>   static inline void superio_select(int base, int ld);
>   static inline void superio_exit(int base);
>
> @@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
>   	return val;
>   }
>
> -static inline void superio_enter(int base)
> +static inline int superio_enter(int base)
>   {
> +	/* Don't step on other drivers' I/O space by accident */
> +	if (!request_muxed_region(base, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				(int)base);
> +		return -EBUSY;
> +	}
> +
>   	/* according to the datasheet the key must be send twice! */
>   	outb(SIO_UNLOCK_KEY, base);
>   	outb(SIO_UNLOCK_KEY, base);
> +
> +	return 0;
>   }
>
>   static inline void superio_select(int base, int ld)
> @@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
>   static inline void superio_exit(int base)
>   {
>   	outb(SIO_LOCK_KEY, base);
> +	release_region(base, 2);
>   }
>
>   static inline int fan_from_reg(u16 reg)
> @@ -2239,17 +2249,10 @@ static int f71882fg_remove(struct platform_device *pdev)
>   static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   	struct f71882fg_sio_data *sio_data)
>   {
> -	int err = -ENODEV;
>   	u16 devid;
> -
> -	/* Don't step on other drivers' I/O space by accident */
> -	if (!request_region(sioaddr, 2, DRVNAME)) {
> -		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> -				(int)sioaddr);
> -		return -EBUSY;
> -	}
> -
> -	superio_enter(sioaddr);
> +	int err = superio_enter(sioaddr);
> +	if (err)
> +		return err;
>
>   	devid = superio_inw(sioaddr, SIO_REG_MANID);
>   	if (devid != SIO_FINTEK_ID) {
> @@ -2306,7 +2309,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> -	release_region(sioaddr, 2);
>   	return err;
>   }
>

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource
@ 2010-03-25 21:10                                 ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-03-25 21:10 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

On 03/25/2010 02:17 PM, Giel van Schijndel wrote:
> Sleep while acquiring a resource lock on the Super I/O port. This should
> prevent collisions from causing the hardware probe to fail with -EBUSY.
>

Looks good to me (assuming the previous patch in the series gets applied).
Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

hans

> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |   28 +++++++++++++++-------------
>   1 files changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 7857ed3..e09416d 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
>   /* Super-I/O Function prototypes */
>   static inline int superio_inb(int base, int reg);
>   static inline int superio_inw(int base, int reg);
> -static inline void superio_enter(int base);
> +static inline int superio_enter(int base);
>   static inline void superio_select(int base, int ld);
>   static inline void superio_exit(int base);
>
> @@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
>   	return val;
>   }
>
> -static inline void superio_enter(int base)
> +static inline int superio_enter(int base)
>   {
> +	/* Don't step on other drivers' I/O space by accident */
> +	if (!request_muxed_region(base, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				(int)base);
> +		return -EBUSY;
> +	}
> +
>   	/* according to the datasheet the key must be send twice! */
>   	outb(SIO_UNLOCK_KEY, base);
>   	outb(SIO_UNLOCK_KEY, base);
> +
> +	return 0;
>   }
>
>   static inline void superio_select(int base, int ld)
> @@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
>   static inline void superio_exit(int base)
>   {
>   	outb(SIO_LOCK_KEY, base);
> +	release_region(base, 2);
>   }
>
>   static inline int fan_from_reg(u16 reg)
> @@ -2239,17 +2249,10 @@ static int f71882fg_remove(struct platform_device *pdev)
>   static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   	struct f71882fg_sio_data *sio_data)
>   {
> -	int err = -ENODEV;
>   	u16 devid;
> -
> -	/* Don't step on other drivers' I/O space by accident */
> -	if (!request_region(sioaddr, 2, DRVNAME)) {
> -		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> -				(int)sioaddr);
> -		return -EBUSY;
> -	}
> -
> -	superio_enter(sioaddr);
> +	int err = superio_enter(sioaddr);
> +	if (err)
> +		return err;
>
>   	devid = superio_inw(sioaddr, SIO_REG_MANID);
>   	if (devid != SIO_FINTEK_ID) {
> @@ -2306,7 +2309,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> -	release_region(sioaddr, 2);
>   	return err;
>   }
>

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-25 18:16                                   ` [lm-sensors] " Alan Cox
@ 2010-03-29  8:18                                     ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-29  8:18 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Jesse Barnes,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 494 bytes --]

On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
>> +			if (res->flags & IORESOURCE_MUXED)
>> +				wake_up(&muxed_resource_wait);
>>  			kfree(res);
>>  			return;
> 
> And you'll want a
> 
> Signed-off-by: Alan Cox <alan@linux.intel.com>

Yes, thanks.

Anyone specific I should mail to get this patch applied? I don't see any
entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29  8:18                                     ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-29  8:18 UTC (permalink / raw)
  To: Alan Cox
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Jesse Barnes,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 494 bytes --]

On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
>> +			if (res->flags & IORESOURCE_MUXED)
>> +				wake_up(&muxed_resource_wait);
>>  			kfree(res);
>>  			return;
> 
> And you'll want a
> 
> Signed-off-by: Alan Cox <alan@linux.intel.com>

Yes, thanks.

Anyone specific I should mail to get this patch applied? I don't see any
entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29  8:18                                     ` [lm-sensors] " Giel van Schijndel
@ 2010-03-29 16:07                                       ` Jesse Barnes
  -1 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-03-29 16:07 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 10:18:34 +0200
Giel van Schijndel <me@mortis.eu> wrote:

> On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
> >> +			if (res->flags & IORESOURCE_MUXED)
> >> +				wake_up(&muxed_resource_wait);
> >>  			kfree(res);
> >>  			return;
> > 
> > And you'll want a
> > 
> > Signed-off-by: Alan Cox <alan@linux.intel.com>
> 
> Yes, thanks.
> 
> Anyone specific I should mail to get this patch applied? I don't see any
> entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.

I can take it; sometimes Linus applies resource stuff directly though.

Can you resend with the appropriate s-o-bs etc?

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 16:07                                       ` Jesse Barnes
  0 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-03-29 16:07 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 10:18:34 +0200
Giel van Schijndel <me@mortis.eu> wrote:

> On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
> >> +			if (res->flags & IORESOURCE_MUXED)
> >> +				wake_up(&muxed_resource_wait);
> >>  			kfree(res);
> >>  			return;
> > 
> > And you'll want a
> > 
> > Signed-off-by: Alan Cox <alan@linux.intel.com>
> 
> Yes, thanks.
> 
> Anyone specific I should mail to get this patch applied? I don't see any
> entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.

I can take it; sometimes Linus applies resource stuff directly though.

Can you resend with the appropriate s-o-bs etc?

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 16:07                                       ` [lm-sensors] " Jesse Barnes
@ 2010-03-29 17:38                                         ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-29 17:38 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5048 bytes --]

On Mon, Mar 29, 2010 at 09:07:13AM -0700, Jesse Barnes wrote:
> On Mon, 29 Mar 2010 10:18:34 +0200> Giel van Schijndel wrote:
>> On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
>>>> +			if (res->flags & IORESOURCE_MUXED)
>>>> +				wake_up(&muxed_resource_wait);
>>>>  			kfree(res);
>>>>  			return;
>>> 
>>> And you'll want a
>>> 
>>> Signed-off-by: Alan Cox <alan@linux.intel.com>
>> 
>> Yes, thanks.
>> 
>> Anyone specific I should mail to get this patch applied? I don't see any
>> entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.
> 
> I can take it; sometimes Linus applies resource stuff directly though.
> 
> Can you resend with the appropriate s-o-bs etc?

Sure.

(I copied Alan's signed-off-by from his reply to the patch)

Patch after this line:
========================================================================
resource: shared I/O region support

SuperIO devices share regions and use lock/unlock operations to chip
select.  We therefore need to be able to request a resource and wait for
it to be freed by whichever other SuperIO device currently hogs it.
Right now you have to poll which is horrible.

Add a MUXED field to IO port resources. If the MUXED field is set on the
resource and on the request (via request_muxed_region) then we block
until the previous owner of the muxed resource releases their region.

This allows us to implement proper resource sharing and locking for
superio chips using code of the form

enable_my_superio_dev() {
	request_muxed_region(0x44, 0x02, "superio:watchdog");
	outb() ..sequence to enable chip
}

disable_my_superio_dev() {
	outb() .. sequence of disable chip
	release_region(0x44, 0x02);
}

Signed-off-by: Giel van Schijndel <me@mortis.eu>
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
 include/linux/ioport.h |    4 +++-
 kernel/resource.c      |   16 +++++++++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 71ab79d..604fd29 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -52,6 +52,7 @@ struct resource_list {
 
 #define IORESOURCE_MEM_64	0x00100000
 #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
+#define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
 
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_DISABLED	0x10000000
@@ -141,7 +142,8 @@ static inline unsigned long resource_type(const struct resource *res)
 }
 
 /* Convenience shorthand with allocation */
-#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_region(start,n,name)		__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_muxed_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
 #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
 #define request_mem_region_exclusive(start,n,name) \
diff --git a/kernel/resource.c b/kernel/resource.c
index 2d5be5d..ab44c7f 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -15,6 +15,7 @@
 #include <linux/spinlock.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/pfn.h>
@@ -651,6 +652,8 @@ resource_size_t resource_alignment(struct resource *res)
  * release_region releases a matching busy region.
  */
 
+static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
+
 /**
  * __request_region - create a new busy resource region
  * @parent: parent resource descriptor
@@ -663,6 +666,7 @@ struct resource * __request_region(struct resource *parent,
 				   resource_size_t start, resource_size_t n,
 				   const char *name, int flags)
 {
+	DECLARE_WAITQUEUE(wait, current);
 	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (!res)
@@ -687,7 +691,15 @@ struct resource * __request_region(struct resource *parent,
 			if (!(conflict->flags & IORESOURCE_BUSY))
 				continue;
 		}
-
+		if (conflict->flags & flags & IORESOURCE_MUXED) {
+			add_wait_queue(&muxed_resource_wait, &wait);
+			write_unlock(&resource_lock);
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule();
+			remove_wait_queue(&muxed_resource_wait, &wait);
+			write_lock(&resource_lock);
+			continue;
+		}
 		/* Uhhuh, that didn't work out.. */
 		kfree(res);
 		res = NULL;
@@ -761,6 +773,8 @@ void __release_region(struct resource *parent, resource_size_t start,
 				break;
 			*p = res->sibling;
 			write_unlock(&resource_lock);
+			if (res->flags & IORESOURCE_MUXED)
+				wake_up(&muxed_resource_wait);
 			kfree(res);
 			return;
 		}
-- 
1.6.4.4

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 17:38                                         ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-29 17:38 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 5048 bytes --]

On Mon, Mar 29, 2010 at 09:07:13AM -0700, Jesse Barnes wrote:
> On Mon, 29 Mar 2010 10:18:34 +0200> Giel van Schijndel wrote:
>> On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
>>>> +			if (res->flags & IORESOURCE_MUXED)
>>>> +				wake_up(&muxed_resource_wait);
>>>>  			kfree(res);
>>>>  			return;
>>> 
>>> And you'll want a
>>> 
>>> Signed-off-by: Alan Cox <alan@linux.intel.com>
>> 
>> Yes, thanks.
>> 
>> Anyone specific I should mail to get this patch applied? I don't see any
>> entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.
> 
> I can take it; sometimes Linus applies resource stuff directly though.
> 
> Can you resend with the appropriate s-o-bs etc?

Sure.

(I copied Alan's signed-off-by from his reply to the patch)

Patch after this line:
========================================================================
resource: shared I/O region support

SuperIO devices share regions and use lock/unlock operations to chip
select.  We therefore need to be able to request a resource and wait for
it to be freed by whichever other SuperIO device currently hogs it.
Right now you have to poll which is horrible.

Add a MUXED field to IO port resources. If the MUXED field is set on the
resource and on the request (via request_muxed_region) then we block
until the previous owner of the muxed resource releases their region.

This allows us to implement proper resource sharing and locking for
superio chips using code of the form

enable_my_superio_dev() {
	request_muxed_region(0x44, 0x02, "superio:watchdog");
	outb() ..sequence to enable chip
}

disable_my_superio_dev() {
	outb() .. sequence of disable chip
	release_region(0x44, 0x02);
}

Signed-off-by: Giel van Schijndel <me@mortis.eu>
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
 include/linux/ioport.h |    4 +++-
 kernel/resource.c      |   16 +++++++++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 71ab79d..604fd29 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -52,6 +52,7 @@ struct resource_list {
 
 #define IORESOURCE_MEM_64	0x00100000
 #define IORESOURCE_WINDOW	0x00200000	/* forwarded by bridge */
+#define IORESOURCE_MUXED	0x00400000	/* Resource is software muxed */
 
 #define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
 #define IORESOURCE_DISABLED	0x10000000
@@ -141,7 +142,8 @@ static inline unsigned long resource_type(const struct resource *res)
 }
 
 /* Convenience shorthand with allocation */
-#define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_region(start,n,name)		__request_region(&ioport_resource, (start), (n), (name), 0)
+#define request_muxed_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
 #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)
 #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)
 #define request_mem_region_exclusive(start,n,name) \
diff --git a/kernel/resource.c b/kernel/resource.c
index 2d5be5d..ab44c7f 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -15,6 +15,7 @@
 #include <linux/spinlock.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
+#include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/pfn.h>
@@ -651,6 +652,8 @@ resource_size_t resource_alignment(struct resource *res)
  * release_region releases a matching busy region.
  */
 
+static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
+
 /**
  * __request_region - create a new busy resource region
  * @parent: parent resource descriptor
@@ -663,6 +666,7 @@ struct resource * __request_region(struct resource *parent,
 				   resource_size_t start, resource_size_t n,
 				   const char *name, int flags)
 {
+	DECLARE_WAITQUEUE(wait, current);
 	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (!res)
@@ -687,7 +691,15 @@ struct resource * __request_region(struct resource *parent,
 			if (!(conflict->flags & IORESOURCE_BUSY))
 				continue;
 		}
-
+		if (conflict->flags & flags & IORESOURCE_MUXED) {
+			add_wait_queue(&muxed_resource_wait, &wait);
+			write_unlock(&resource_lock);
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule();
+			remove_wait_queue(&muxed_resource_wait, &wait);
+			write_lock(&resource_lock);
+			continue;
+		}
 		/* Uhhuh, that didn't work out.. */
 		kfree(res);
 		res = NULL;
@@ -761,6 +773,8 @@ void __release_region(struct resource *parent, resource_size_t start,
 				break;
 			*p = res->sibling;
 			write_unlock(&resource_lock);
+			if (res->flags & IORESOURCE_MUXED)
+				wake_up(&muxed_resource_wait);
 			kfree(res);
 			return;
 		}
-- 
1.6.4.4

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 17:38                                         ` [lm-sensors] " Giel van Schijndel
@ 2010-03-29 17:44                                           ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-29 17:44 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 809 bytes --]

On Mon, Mar 29, 2010 at 07:38:00PM +0200, Giel van Schijndel wrote:
> On Mon, Mar 29, 2010 at 09:07:13AM -0700, Jesse Barnes wrote:
>> I can take it; sometimes Linus applies resource stuff directly though.
>> 
>> Can you resend with the appropriate s-o-bs etc?
> 
> Sure.
> 
> (I copied Alan's signed-off-by from his reply to the patch)
> 
> Patch after this line:
> ... snip ...

PS (to be sure authorship is maintained):
> This patch was originally written by Alan Cox [1]. I only updated it to
> apply correctly to Linus' current tree and changed IORESOURCE_MUXED's
> value from 0x00200000 to 0x00400000 because the former has already been
> taken in use since.
>  
> [1] https://patchwork.kernel.org/patch/32397/

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 17:44                                           ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-29 17:44 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 809 bytes --]

On Mon, Mar 29, 2010 at 07:38:00PM +0200, Giel van Schijndel wrote:
> On Mon, Mar 29, 2010 at 09:07:13AM -0700, Jesse Barnes wrote:
>> I can take it; sometimes Linus applies resource stuff directly though.
>> 
>> Can you resend with the appropriate s-o-bs etc?
> 
> Sure.
> 
> (I copied Alan's signed-off-by from his reply to the patch)
> 
> Patch after this line:
> ... snip ...

PS (to be sure authorship is maintained):
> This patch was originally written by Alan Cox [1]. I only updated it to
> apply correctly to Linus' current tree and changed IORESOURCE_MUXED's
> value from 0x00200000 to 0x00400000 because the former has already been
> taken in use since.
>  
> [1] https://patchwork.kernel.org/patch/32397/

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 17:38                                         ` [lm-sensors] " Giel van Schijndel
@ 2010-03-29 17:45                                           ` H. Peter Anvin
  -1 siblings, 0 replies; 159+ messages in thread
From: H. Peter Anvin @ 2010-03-29 17:45 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jesse Barnes, Alan Cox, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On 03/29/2010 10:38 AM, Giel van Schijndel wrote:
> 
> Patch after this line:
> ========================================================================
> resource: shared I/O region support
> 
> SuperIO devices share regions and use lock/unlock operations to chip
> select.  We therefore need to be able to request a resource and wait for
> it to be freed by whichever other SuperIO device currently hogs it.
> Right now you have to poll which is horrible.
> 
> Add a MUXED field to IO port resources. If the MUXED field is set on the
> resource and on the request (via request_muxed_region) then we block
> until the previous owner of the muxed resource releases their region.
> 
> This allows us to implement proper resource sharing and locking for
> superio chips using code of the form
> 
> enable_my_superio_dev() {
> 	request_muxed_region(0x44, 0x02, "superio:watchdog");
> 	outb() ..sequence to enable chip
> }
> 
> disable_my_superio_dev() {
> 	outb() .. sequence of disable chip
> 	release_region(0x44, 0x02);
> }
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>
> Signed-off-by: Alan Cox <alan@linux.intel.com>

I have to question this approach a bit.

I would much rather see this as a two-step process, where multiple
devices request the same region with a "sharable" flag, and then have a
mutex associated with the struct resource (perhaps we need an outer
container called "struct muxed_resource" or some such.)

What I *really* object to with this patch is that it inherently assumes
that there is only one multiplexed resource in the entire system... but
of course nowhere enforces that.

	-hpa

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 17:45                                           ` H. Peter Anvin
  0 siblings, 0 replies; 159+ messages in thread
From: H. Peter Anvin @ 2010-03-29 17:45 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jesse Barnes, Alan Cox, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On 03/29/2010 10:38 AM, Giel van Schijndel wrote:
> 
> Patch after this line:
> ====================================
> resource: shared I/O region support
> 
> SuperIO devices share regions and use lock/unlock operations to chip
> select.  We therefore need to be able to request a resource and wait for
> it to be freed by whichever other SuperIO device currently hogs it.
> Right now you have to poll which is horrible.
> 
> Add a MUXED field to IO port resources. If the MUXED field is set on the
> resource and on the request (via request_muxed_region) then we block
> until the previous owner of the muxed resource releases their region.
> 
> This allows us to implement proper resource sharing and locking for
> superio chips using code of the form
> 
> enable_my_superio_dev() {
> 	request_muxed_region(0x44, 0x02, "superio:watchdog");
> 	outb() ..sequence to enable chip
> }
> 
> disable_my_superio_dev() {
> 	outb() .. sequence of disable chip
> 	release_region(0x44, 0x02);
> }
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>
> Signed-off-by: Alan Cox <alan@linux.intel.com>

I have to question this approach a bit.

I would much rather see this as a two-step process, where multiple
devices request the same region with a "sharable" flag, and then have a
mutex associated with the struct resource (perhaps we need an outer
container called "struct muxed_resource" or some such.)

What I *really* object to with this patch is that it inherently assumes
that there is only one multiplexed resource in the entire system... but
of course nowhere enforces that.

	-hpa

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 17:38                                         ` [lm-sensors] " Giel van Schijndel
@ 2010-03-29 17:59                                           ` Jesse Barnes
  -1 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-03-29 17:59 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 19:38:00 +0200
Giel van Schijndel <me@mortis.eu> wrote:

> On Mon, Mar 29, 2010 at 09:07:13AM -0700, Jesse Barnes wrote:
> > On Mon, 29 Mar 2010 10:18:34 +0200> Giel van Schijndel wrote:
> >> On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
> >>>> +			if (res->flags & IORESOURCE_MUXED)
> >>>> +				wake_up(&muxed_resource_wait);
> >>>>  			kfree(res);
> >>>>  			return;
> >>> 
> >>> And you'll want a
> >>> 
> >>> Signed-off-by: Alan Cox <alan@linux.intel.com>
> >> 
> >> Yes, thanks.
> >> 
> >> Anyone specific I should mail to get this patch applied? I don't see any
> >> entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.
> > 
> > I can take it; sometimes Linus applies resource stuff directly though.
> > 
> > Can you resend with the appropriate s-o-bs etc?
> 
> Sure.
> 
> (I copied Alan's signed-off-by from his reply to the patch)

Applied to my for-linus branch with Alan as author.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 17:59                                           ` Jesse Barnes
  0 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-03-29 17:59 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 19:38:00 +0200
Giel van Schijndel <me@mortis.eu> wrote:

> On Mon, Mar 29, 2010 at 09:07:13AM -0700, Jesse Barnes wrote:
> > On Mon, 29 Mar 2010 10:18:34 +0200> Giel van Schijndel wrote:
> >> On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
> >>>> +			if (res->flags & IORESOURCE_MUXED)
> >>>> +				wake_up(&muxed_resource_wait);
> >>>>  			kfree(res);
> >>>>  			return;
> >>> 
> >>> And you'll want a
> >>> 
> >>> Signed-off-by: Alan Cox <alan@linux.intel.com>
> >> 
> >> Yes, thanks.
> >> 
> >> Anyone specific I should mail to get this patch applied? I don't see any
> >> entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.
> > 
> > I can take it; sometimes Linus applies resource stuff directly though.
> > 
> > Can you resend with the appropriate s-o-bs etc?
> 
> Sure.
> 
> (I copied Alan's signed-off-by from his reply to the patch)

Applied to my for-linus branch with Alan as author.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 17:38                                         ` [lm-sensors] " Giel van Schijndel
@ 2010-03-29 17:59                                           ` Jesse Barnes
  -1 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-03-29 17:59 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 19:38:00 +0200
Giel van Schijndel <me@mortis.eu> wrote:

> On Mon, Mar 29, 2010 at 09:07:13AM -0700, Jesse Barnes wrote:
> > On Mon, 29 Mar 2010 10:18:34 +0200> Giel van Schijndel wrote:
> >> On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
> >>>> +			if (res->flags & IORESOURCE_MUXED)
> >>>> +				wake_up(&muxed_resource_wait);
> >>>>  			kfree(res);
> >>>>  			return;
> >>> 
> >>> And you'll want a
> >>> 
> >>> Signed-off-by: Alan Cox <alan@linux.intel.com>
> >> 
> >> Yes, thanks.
> >> 
> >> Anyone specific I should mail to get this patch applied? I don't see any
> >> entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.
> > 
> > I can take it; sometimes Linus applies resource stuff directly though.
> > 
> > Can you resend with the appropriate s-o-bs etc?
> 
> Sure.
> 
> (I copied Alan's signed-off-by from his reply to the patch)

...looking again I see it should be in my linux-next branch instead,
I'll move it over.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 17:59                                           ` Jesse Barnes
  0 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-03-29 17:59 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Alan Cox, Hans de Goede, Jean Delvare, Jonathan Cameron,
	H. Peter Anvin, Andrew Morton, Bjorn Helgaas, Dominik Brodowski,
	Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 19:38:00 +0200
Giel van Schijndel <me@mortis.eu> wrote:

> On Mon, Mar 29, 2010 at 09:07:13AM -0700, Jesse Barnes wrote:
> > On Mon, 29 Mar 2010 10:18:34 +0200> Giel van Schijndel wrote:
> >> On Thu, Mar 25, 2010 at 06:16:33PM +0000, Alan Cox wrote:
> >>>> +			if (res->flags & IORESOURCE_MUXED)
> >>>> +				wake_up(&muxed_resource_wait);
> >>>>  			kfree(res);
> >>>>  			return;
> >>> 
> >>> And you'll want a
> >>> 
> >>> Signed-off-by: Alan Cox <alan@linux.intel.com>
> >> 
> >> Yes, thanks.
> >> 
> >> Anyone specific I should mail to get this patch applied? I don't see any
> >> entry in MAINTAINERS for kernel/resource.c or include/linux/resource.h.
> > 
> > I can take it; sometimes Linus applies resource stuff directly though.
> > 
> > Can you resend with the appropriate s-o-bs etc?
> 
> Sure.
> 
> (I copied Alan's signed-off-by from his reply to the patch)

...looking again I see it should be in my linux-next branch instead,
I'll move it over.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 17:45                                           ` [lm-sensors] " H. Peter Anvin
@ 2010-03-29 18:06                                             ` Jesse Barnes
  -1 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-03-29 18:06 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Giel van Schijndel, Alan Cox, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 10:45:35 -0700
"H. Peter Anvin" <hpa@zytor.com> wrote:

> On 03/29/2010 10:38 AM, Giel van Schijndel wrote:
> > 
> > Patch after this line:
> > ========================================================================
> > resource: shared I/O region support
> > 
> > SuperIO devices share regions and use lock/unlock operations to chip
> > select.  We therefore need to be able to request a resource and wait for
> > it to be freed by whichever other SuperIO device currently hogs it.
> > Right now you have to poll which is horrible.
> > 
> > Add a MUXED field to IO port resources. If the MUXED field is set on the
> > resource and on the request (via request_muxed_region) then we block
> > until the previous owner of the muxed resource releases their region.
> > 
> > This allows us to implement proper resource sharing and locking for
> > superio chips using code of the form
> > 
> > enable_my_superio_dev() {
> > 	request_muxed_region(0x44, 0x02, "superio:watchdog");
> > 	outb() ..sequence to enable chip
> > }
> > 
> > disable_my_superio_dev() {
> > 	outb() .. sequence of disable chip
> > 	release_region(0x44, 0x02);
> > }
> > 
> > Signed-off-by: Giel van Schijndel <me@mortis.eu>
> > Signed-off-by: Alan Cox <alan@linux.intel.com>
> 
> I have to question this approach a bit.
> 
> I would much rather see this as a two-step process, where multiple
> devices request the same region with a "sharable" flag, and then have a
> mutex associated with the struct resource (perhaps we need an outer
> container called "struct muxed_resource" or some such.)
> 
> What I *really* object to with this patch is that it inherently assumes
> that there is only one multiplexed resource in the entire system... but
> of course nowhere enforces that.

Well that does keep it simple, and with just one user that's probably
best.

But why not use the common bus driver method?  Muxing at the resource
level only seems to solve part of the problem...  It doesn't guarantee
for example that driver A does something to a shared region that breaks
driver B; it just makes sure they don't access the same region at the
same time.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 18:06                                             ` Jesse Barnes
  0 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-03-29 18:06 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Giel van Schijndel, Alan Cox, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 10:45:35 -0700
"H. Peter Anvin" <hpa@zytor.com> wrote:

> On 03/29/2010 10:38 AM, Giel van Schijndel wrote:
> > 
> > Patch after this line:
> > ====================================
> > resource: shared I/O region support
> > 
> > SuperIO devices share regions and use lock/unlock operations to chip
> > select.  We therefore need to be able to request a resource and wait for
> > it to be freed by whichever other SuperIO device currently hogs it.
> > Right now you have to poll which is horrible.
> > 
> > Add a MUXED field to IO port resources. If the MUXED field is set on the
> > resource and on the request (via request_muxed_region) then we block
> > until the previous owner of the muxed resource releases their region.
> > 
> > This allows us to implement proper resource sharing and locking for
> > superio chips using code of the form
> > 
> > enable_my_superio_dev() {
> > 	request_muxed_region(0x44, 0x02, "superio:watchdog");
> > 	outb() ..sequence to enable chip
> > }
> > 
> > disable_my_superio_dev() {
> > 	outb() .. sequence of disable chip
> > 	release_region(0x44, 0x02);
> > }
> > 
> > Signed-off-by: Giel van Schijndel <me@mortis.eu>
> > Signed-off-by: Alan Cox <alan@linux.intel.com>
> 
> I have to question this approach a bit.
> 
> I would much rather see this as a two-step process, where multiple
> devices request the same region with a "sharable" flag, and then have a
> mutex associated with the struct resource (perhaps we need an outer
> container called "struct muxed_resource" or some such.)
> 
> What I *really* object to with this patch is that it inherently assumes
> that there is only one multiplexed resource in the entire system... but
> of course nowhere enforces that.

Well that does keep it simple, and with just one user that's probably
best.

But why not use the common bus driver method?  Muxing at the resource
level only seems to solve part of the problem...  It doesn't guarantee
for example that driver A does something to a shared region that breaks
driver B; it just makes sure they don't access the same region at the
same time.

-- 
Jesse Barnes, Intel Open Source Technology Center

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 18:06                                             ` [lm-sensors] " Jesse Barnes
@ 2010-03-29 18:17                                               ` H. Peter Anvin
  -1 siblings, 0 replies; 159+ messages in thread
From: H. Peter Anvin @ 2010-03-29 18:17 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Giel van Schijndel, Alan Cox, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On 03/29/2010 11:06 AM, Jesse Barnes wrote:
>>
>> I have to question this approach a bit.
>>
>> I would much rather see this as a two-step process, where multiple
>> devices request the same region with a "sharable" flag, and then have a
>> mutex associated with the struct resource (perhaps we need an outer
>> container called "struct muxed_resource" or some such.)
>>
>> What I *really* object to with this patch is that it inherently assumes
>> that there is only one multiplexed resource in the entire system... but
>> of course nowhere enforces that.
> 
> Well that does keep it simple, and with just one user that's probably
> best.
> 
> But why not use the common bus driver method?  Muxing at the resource
> level only seems to solve part of the problem...  It doesn't guarantee
> for example that driver A does something to a shared region that breaks
> driver B; it just makes sure they don't access the same region at the
> same time.
> 

The common bus driver method is the obvious thing to do, but it would
presumably be greatly helped by librarization.

	-hpa

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 18:17                                               ` H. Peter Anvin
  0 siblings, 0 replies; 159+ messages in thread
From: H. Peter Anvin @ 2010-03-29 18:17 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Giel van Schijndel, Alan Cox, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On 03/29/2010 11:06 AM, Jesse Barnes wrote:
>>
>> I have to question this approach a bit.
>>
>> I would much rather see this as a two-step process, where multiple
>> devices request the same region with a "sharable" flag, and then have a
>> mutex associated with the struct resource (perhaps we need an outer
>> container called "struct muxed_resource" or some such.)
>>
>> What I *really* object to with this patch is that it inherently assumes
>> that there is only one multiplexed resource in the entire system... but
>> of course nowhere enforces that.
> 
> Well that does keep it simple, and with just one user that's probably
> best.
> 
> But why not use the common bus driver method?  Muxing at the resource
> level only seems to solve part of the problem...  It doesn't guarantee
> for example that driver A does something to a shared region that breaks
> driver B; it just makes sure they don't access the same region at the
> same time.
> 

The common bus driver method is the obvious thing to do, but it would
presumably be greatly helped by librarization.

	-hpa

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 18:06                                             ` [lm-sensors] " Jesse Barnes
@ 2010-03-29 18:29                                               ` Alan Cox
  -1 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-29 18:29 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: H. Peter Anvin, Giel van Schijndel, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

> Well that does keep it simple, and with just one user that's probably
> best.
> 
> But why not use the common bus driver method?  Muxing at the resource
> level only seems to solve part of the problem...  It doesn't guarantee
> for example that driver A does something to a shared region that breaks
> driver B; it just makes sure they don't access the same region at the
> same time.

The obvious reason for not doing that kind of grand over-engineering is
that you are assuming the devices involved are remotely related. On quite
a few systems we have a collection of superio config interfaces on random
low ports all with their own lock/unlock rituals. They range from
parallel devices to watchdogs and god knows what else. Right now we have
various bits of driver code (parport is a good one) that exist on a cross
fingers, pray and poke model. It would be nice to fix that.

For most super I/O devices the muxing is basically a glorified chip select
line. There isn't any structure to impose over it. Where you have
structure there are better ways to do it, but one does not exclude the
other.

Alan

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 18:29                                               ` Alan Cox
  0 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-29 18:29 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: H. Peter Anvin, Giel van Schijndel, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

> Well that does keep it simple, and with just one user that's probably
> best.
> 
> But why not use the common bus driver method?  Muxing at the resource
> level only seems to solve part of the problem...  It doesn't guarantee
> for example that driver A does something to a shared region that breaks
> driver B; it just makes sure they don't access the same region at the
> same time.

The obvious reason for not doing that kind of grand over-engineering is
that you are assuming the devices involved are remotely related. On quite
a few systems we have a collection of superio config interfaces on random
low ports all with their own lock/unlock rituals. They range from
parallel devices to watchdogs and god knows what else. Right now we have
various bits of driver code (parport is a good one) that exist on a cross
fingers, pray and poke model. It would be nice to fix that.

For most super I/O devices the muxing is basically a glorified chip select
line. There isn't any structure to impose over it. Where you have
structure there are better ways to do it, but one does not exclude the
other.

Alan

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 17:45                                           ` [lm-sensors] " H. Peter Anvin
@ 2010-03-29 18:39                                             ` Alan Cox
  -1 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-29 18:39 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Giel van Schijndel, Jesse Barnes, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

> What I *really* object to with this patch is that it inherently assumes
> that there is only one multiplexed resource in the entire system... but
> of course nowhere enforces that.

The patch does nothing of the sort. Not unless there is a bug I am not
seeing anyway. It does assume nobody tries to grab pairs of such
resources as it doesn't do deadlock avoidance.

It's now a shared resource patch however, its a multiplexor patch and
that is precisely why it is called MUX not SHARED or OVERLAY
Alan

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 18:39                                             ` Alan Cox
  0 siblings, 0 replies; 159+ messages in thread
From: Alan Cox @ 2010-03-29 18:39 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Giel van Schijndel, Jesse Barnes, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

> What I *really* object to with this patch is that it inherently assumes
> that there is only one multiplexed resource in the entire system... but
> of course nowhere enforces that.

The patch does nothing of the sort. Not unless there is a bug I am not
seeing anyway. It does assume nobody tries to grab pairs of such
resources as it doesn't do deadlock avoidance.

It's now a shared resource patch however, its a multiplexor patch and
that is precisely why it is called MUX not SHARED or OVERLAY
Alan

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 18:39                                             ` [lm-sensors] " Alan Cox
@ 2010-03-29 18:56                                               ` H. Peter Anvin
  -1 siblings, 0 replies; 159+ messages in thread
From: H. Peter Anvin @ 2010-03-29 18:56 UTC (permalink / raw)
  To: Alan Cox
  Cc: Giel van Schijndel, Jesse Barnes, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On 03/29/2010 11:39 AM, Alan Cox wrote:
>> What I *really* object to with this patch is that it inherently assumes
>> that there is only one multiplexed resource in the entire system... but
>> of course nowhere enforces that.
> 
> The patch does nothing of the sort. Not unless there is a bug I am not
> seeing anyway. It does assume nobody tries to grab pairs of such
> resources as it doesn't do deadlock avoidance.
> 
> It's now a shared resource patch however, its a multiplexor patch and
> that is precisely why it is called MUX not SHARED or OVERLAY
> Alan

Sorry, I missed the "continue", which of course handles the situation I
was worried about.  The shared wait queue is a bit inelegant, but if it
turns out to be a bottleneck in real life then we either have bigger
problems or it can be addressed at that time.

	-hpa


^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-03-29 18:56                                               ` H. Peter Anvin
  0 siblings, 0 replies; 159+ messages in thread
From: H. Peter Anvin @ 2010-03-29 18:56 UTC (permalink / raw)
  To: Alan Cox
  Cc: Giel van Schijndel, Jesse Barnes, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On 03/29/2010 11:39 AM, Alan Cox wrote:
>> What I *really* object to with this patch is that it inherently assumes
>> that there is only one multiplexed resource in the entire system... but
>> of course nowhere enforces that.
> 
> The patch does nothing of the sort. Not unless there is a bug I am not
> seeing anyway. It does assume nobody tries to grab pairs of such
> resources as it doesn't do deadlock avoidance.
> 
> It's now a shared resource patch however, its a multiplexor patch and
> that is precisely why it is called MUX not SHARED or OVERLAY
> Alan

Sorry, I missed the "continue", which of course handles the situation I
was worried about.  The shared wait queue is a bit inelegant, but if it
turns out to be a bottleneck in real life then we either have bigger
problems or it can be addressed at that time.

	-hpa


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E
  2010-03-25 13:17                                 ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog Giel van Schijndel
@ 2010-03-30  9:06                                   ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-30  9:06 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Wim Van Sebroeck,
	Laurens Leemans, lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 23428 bytes --]

On Thu, Mar 25, 2010 at 02:17:43PM +0100, Giel van Schijndel wrote:
> Add a new watchdog driver for the Fintek F71808E Super I/O chip.

Updated patch:
 * fixes a bug where detection wouldn't function properly if a
   non-Fintek device was found (or a wrong Super I/O port chosen).
 * Add support for the F71882FG

NOTE: This patch depends on patch [1] (applied in [2]) and patch [3].

[1] https://patchwork.kernel.org/patch/89023/
[2] http://git.kernel.org/?p=linux/kernel/git/jbarnes/pci-2.6.git;a=commit;h=316607809324cc796c0809630b6ae8a768404296
[3] https://patchwork.kernel.org/patch/88235/

Patch after this line:
========================================================================
[RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E

Add a new watchdog driver for the Fintek F71808E Super I/O chip.
---
 drivers/watchdog/Kconfig       |   11 +
 drivers/watchdog/Makefile      |    1 +
 drivers/watchdog/f71808e_wdt.c |  767 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 779 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/f71808e_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 050ee14..d973105 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -366,6 +366,17 @@ config ALIM7101_WDT
 
 	  Most people will say N.
 
+config F71808E_WDT
+	tristate "Fintek F71808E Watchdog"
+	depends on X86 && EXPERIMENTAL
+	help
+	  This is the driver for the hardware watchdog on the Fintek
+	  F71808E Super I/O chip.
+
+	  You can compile this driver directly into the kernel, or use
+	  it as a module.  The module will be called f71808e_wdt.
+
+
 config GEODE_WDT
 	tristate "AMD Geode CS5535/CS5536 Watchdog"
 	depends on CS5535_MFGPT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 475c611..6f0f3d9 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
 obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
+obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
 obj-$(CONFIG_GEODE_WDT) += geodewdt.o
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
 obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
new file mode 100644
index 0000000..b0314ea
--- /dev/null
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -0,0 +1,767 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
+ *   Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com>           *
+ *   Copyright (C) 2010 Giel van Schijndel <me@mortis.eu>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+
+#define DRVNAME "f71808e_wdt"
+
+#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
+#define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
+#define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
+
+#define SIO_REG_LDSEL		0x07	/* Logical device select */
+#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
+#define SIO_REG_DEVREV		0x22	/* Device revision */
+#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE		0x30	/* Logical device enable */
+#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
+#define SIO_F71858_ID		0x0507  /* Chipset ID */
+#define SIO_F71862_ID		0x0601	/* Chipset ID */
+#define SIO_F71882_ID		0x0541	/* Chipset ID */
+#define SIO_F71889_ID		0x0723	/* Chipset ID */
+
+#define	F71882FG_REG_START		0x01
+
+#define F71808FG_REG_WDO_CONF		0xf0
+#define F71808FG_REG_WDT_CONF		0xf5
+#define F71808FG_REG_WD_TIME		0xf6
+
+#define F71808FG_FLAG_WDOUT_EN		7
+
+#define F71808FG_FLAG_WDTMOUT_STS	5
+#define F71808FG_FLAG_WD_EN		5
+#define F71808FG_FLAG_WD_PULSE		4
+#define F71808FG_FLAG_WD_UNIT		3
+
+/* Default values */
+#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
+#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
+#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
+					   watchdog signal */
+
+static unsigned short force_id;
+module_param(force_id, ushort, 0);
+MODULE_PARM_DESC(force_id, "Override the detected device ID");
+
+static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
+static int timeout = 60;	/* default timeout in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in seconds. 1<= timeout <="
+			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
+			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
+module_param(pulse_width, uint, 0);
+MODULE_PARM_DESC(pulse_width,
+	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
+			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+static unsigned int start_withtimeout;
+module_param(start_withtimeout, uint, 0);
+MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
+	" given initial timeout. Zero (default) disables this feature.");
+
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg };
+
+static const char *f71808e_names[] = {
+	"f71808fg",
+	"f71858fg",
+	"f71862fg",
+	"f71882fg",
+	"f71889fg",
+};
+
+/* Super-I/O Function prototypes */
+static inline int superio_inb(int base, int reg);
+static inline int superio_inw(int base, int reg);
+static inline void superio_outb(int base, int reg, u8 val);
+static inline void superio_set_bit(int base, int reg, int bit);
+static inline void superio_clear_bit(int base, int reg, int bit);
+static inline int superio_enter(int base);
+static inline void superio_select(int base, int ld);
+static inline void superio_exit(int base);
+
+struct watchdog_data {
+	unsigned short	sioaddr;
+	enum chips	type;
+	unsigned long	opened;
+	struct mutex	lock;
+	char		expect_close;
+	struct watchdog_info ident;
+
+	unsigned short	timeout;
+	u8		timer_val;	/* content for the wd_time register */
+	char		minutes_mode;
+	u8		pulse_val;	/* pulse width flag */
+	char		pulse_mode;	/* enable pulse output mode? */
+	char		caused_reboot;	/* last reboot was by the watchdog */
+};
+
+static struct watchdog_data watchdog = {
+	.lock = __MUTEX_INITIALIZER(watchdog.lock),
+};
+
+/* Super I/O functions */
+static inline int superio_inb(int base, int reg)
+{
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static int superio_inw(int base, int reg)
+{
+	int val;
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
+	return val;
+}
+
+static inline void superio_outb(int base, int reg, u8 val)
+{
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static inline void superio_set_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__set_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__clear_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline int superio_enter(int base)
+{
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
+	/* according to the datasheet the key must be send twice! */
+	outb(SIO_UNLOCK_KEY, base);
+	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
+}
+
+static inline void superio_select(int base, int ld)
+{
+	outb(SIO_REG_LDSEL, base);
+	outb(ld, base + 1);
+}
+
+static inline void superio_exit(int base)
+{
+	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
+}
+
+static int watchdog_set_timeout(int timeout)
+{
+	if (timeout <= 0
+	 || timeout >  max_timeout) {
+		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&watchdog.lock);
+
+	watchdog.timeout = timeout;
+	if (timeout > 0xff) {
+		watchdog.timer_val = DIV_ROUND_UP(timeout, 60);
+		watchdog.minutes_mode = true;
+	} else {
+		watchdog.timer_val = timeout;
+		watchdog.minutes_mode = false;
+	}
+
+	mutex_unlock(&watchdog.lock);
+
+	return 0;
+}
+
+static int watchdog_set_pulse_width(unsigned int pw)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+
+	if        (pw <=    1) {
+		watchdog.pulse_val = 0;
+	} else if (pw <=   25) {
+		watchdog.pulse_val = 1;
+	} else if (pw <=  125) {
+		watchdog.pulse_val = 2;
+	} else if (pw <= 5000) {
+		watchdog.pulse_val = 3;
+	} else {
+		printk(KERN_ERR DRVNAME ": pulse width out of range\n");
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+
+	watchdog.pulse_mode = pw;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_keepalive(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	if (watchdog.minutes_mode)
+		/* select minutes for timer units */
+		superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+	else
+		/* select seconds for timer units */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+
+	/* Set timer value */
+	superio_outb(watchdog.sioaddr, F71808FG_REG_WD_TIME,
+			   watchdog.timeout);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_start(void)
+{
+	/* Make sure we don't die as soon as the watchdog is enabled below */
+	int err = watchdog_keepalive();
+	if (err)
+		return err;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	/* Watchdog pin configuration */
+	switch (watchdog.type) {
+	case f71808fg:
+		/* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */
+		superio_clear_bit(watchdog.sioaddr, 0x2a, 3);
+		superio_clear_bit(watchdog.sioaddr, 0x2b, 3);
+		break;
+
+	case f71882fg:
+		/* Set pin 56 to WDTRST# */
+		superio_set_bit(watchdog.sioaddr, 0x29, 1);
+		break;
+
+	default:
+		/*
+		 * 'default' label to shut up the compiler and catch
+		 * programmer errors
+		 */
+		err = -ENODEV;
+		goto exit_superio;
+	}
+
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+	superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0);
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF,
+			F71808FG_FLAG_WDOUT_EN);
+
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	if (watchdog.pulse_mode) {
+		/* Select "pulse" output mode with given duration */
+		u8 wdt_conf = superio_inb(watchdog.sioaddr,
+				F71808FG_REG_WDT_CONF);
+
+		/* Set WD_PSWIDTH bits (1:0) */
+		wdt_conf = (wdt_conf & 0xfc) | (watchdog.pulse_val & 0x03);
+		/* Set WD_PULSE to "pulse" mode */
+		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
+
+		superio_outb(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				wdt_conf);
+	} else {
+		/* Select "level" output mode */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_PULSE);
+	}
+
+exit_superio:
+	superio_exit(watchdog.sioaddr);
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_stop(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_get_status(void)
+{
+	int status = 0;
+
+	mutex_lock(&watchdog.lock);
+	status = (watchdog.caused_reboot) ? WDIOF_CARDRESET : 0;
+	mutex_unlock(&watchdog.lock);
+
+	return status;
+}
+
+static bool watchdog_is_running(void)
+{
+	/*
+	 * if we fail to determine the watchdog's status assume it to be
+	 * running to be on the safe side
+	 */
+	bool is_running = true;
+
+	mutex_lock(&watchdog.lock);
+	if (superio_enter(watchdog.sioaddr))
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0))
+		&& (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) & F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return is_running;
+}
+
+/* /dev/watchdog api */
+
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	int err;
+
+	/* If the watchdog is alive we don't need to start it again */
+	if (test_and_set_bit(0, &watchdog.opened))
+		return -EBUSY;
+
+	err = watchdog_start();
+	if (err) {
+		clear_bit(0, &watchdog.opened);
+		return err;
+	}
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	watchdog.expect_close = 0;
+	return nonseekable_open(inode, file);
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &watchdog.opened);
+
+	if (!watchdog.expect_close) {
+		watchdog_keepalive();
+		printk(KERN_CRIT DRVNAME
+			": Unexpected close, not stopping watchdog!\n");
+	} else if (!nowayout) {
+		watchdog_stop();
+	}
+	return 0;
+}
+
+/*
+ *      watchdog_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t watchdog_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			bool expect_close = false;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				expect_close = (c == 'V');
+			}
+
+			/* Properly order writes across fork()ed processes */
+			mutex_lock(&watchdog.lock);
+			watchdog.expect_close = expect_close;
+			mutex_unlock(&watchdog.lock);
+		}
+
+		/* someone wrote to us, we should restart timer */
+		watchdog_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      watchdog_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+static long watchdog_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	int status;
+	int new_options;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &watchdog.ident,
+			sizeof(watchdog.ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		status = watchdog_get_status();
+		if (status < 0)
+			return status;
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD)
+			watchdog_stop();
+
+		if (new_options & WDIOS_ENABLECARD)
+			return watchdog_start();
+
+
+	case WDIOC_KEEPALIVE:
+		watchdog_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (watchdog_set_timeout(new_timeout))
+			return -EINVAL;
+
+		watchdog_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(watchdog.timeout, uarg.i);
+
+	default:
+		return -ENOTTY;
+
+	}
+}
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		watchdog_stop();
+	return NOTIFY_DONE;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= watchdog_open,
+	.release	= watchdog_release,
+	.write		= watchdog_write,
+	.unlocked_ioctl	= watchdog_ioctl,
+};
+
+static struct miscdevice watchdog_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &watchdog_fops,
+};
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+static int __init watchdog_init(int sioaddr)
+{
+	int wdt_conf, err = 0;
+
+	/* No need to lock watchdog.lock here because no entry points
+	 * into the module have been registered yet.
+	 */
+	watchdog.sioaddr = sioaddr;
+	watchdog.ident.options = WDIOC_SETTIMEOUT
+				| WDIOF_MAGICCLOSE
+				| WDIOF_KEEPALIVEPING;
+
+	snprintf(watchdog.ident.identity,
+		sizeof(watchdog.ident.identity), "%s watchdog",
+		f71808e_names[watchdog.type]);
+
+	err = superio_enter(sioaddr);
+	if (err)
+		return err;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF);
+	watchdog.caused_reboot = wdt_conf & F71808FG_FLAG_WDTMOUT_STS;
+
+	superio_exit(sioaddr);
+
+	err = watchdog_set_timeout(timeout);
+	if (err)
+		return err;
+	err = watchdog_set_pulse_width(pulse_width);
+	if (err)
+		return err;
+
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err)
+		return err;
+
+	err = misc_register(&watchdog_miscdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME
+			": cannot register miscdev on minor=%d\n",
+				watchdog_miscdev.minor);
+		goto exit_reboot;
+	}
+
+	if (start_withtimeout) {
+		if (start_withtimeout <= 0
+		 || start_withtimeout >  max_timeout) {
+			printk(KERN_ERR DRVNAME
+				": starting timeout out of range\n");
+			err = -EINVAL;
+			goto exit_miscdev;
+		}
+
+		err = watchdog_start();
+		if (err) {
+			printk(KERN_ERR DRVNAME
+				": cannot start watchdog timer\n");
+			goto exit_miscdev;
+		}
+
+		mutex_lock(&watchdog.lock);
+		err = superio_enter(sioaddr);
+		if (err)
+			goto exit_unlock;
+		superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+		if (start_withtimeout > 0xff) {
+			/* select minutes for timer units */
+			superio_set_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				DIV_ROUND_UP(start_withtimeout, 60));
+		} else {
+			/* select seconds for timer units */
+			superio_clear_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				start_withtimeout);
+		}
+
+		superio_exit(sioaddr);
+		mutex_unlock(&watchdog.lock);
+
+		if (nowayout)
+			__module_get(THIS_MODULE);
+
+		printk(KERN_INFO DRVNAME
+			": watchdog started with initial timeout of %u sec\n",
+			start_withtimeout);
+	}
+
+	return 0;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+exit_miscdev:
+	misc_deregister(&watchdog_miscdev);
+exit_reboot:
+	unregister_reboot_notifier(&watchdog_notifier);
+
+	return err;
+}
+
+static int __init f71808e_find(int sioaddr)
+{
+	u16 devid;
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
+
+	devid = superio_inw(sioaddr, SIO_REG_MANID);
+	if (devid != SIO_FINTEK_ID) {
+		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
+	switch (devid) {
+	case SIO_F71808_ID:
+		watchdog.type = f71808fg;
+		break;
+	case SIO_F71882_ID:
+		watchdog.type = f71882fg;
+		break;
+	case SIO_F71862_ID:
+	case SIO_F71889_ID:
+		/* These have a watchdog, though it isn't implemented (yet). */
+		err = -ENOSYS;
+		goto exit;
+	case SIO_F71858_ID:
+		/* Confirmed (by datasheet) not to have a watchdog. */
+		err = -ENODEV;
+		goto exit;
+	default:
+		printk(KERN_INFO DRVNAME ": Unrecognized Fintek device: %04x\n",
+		       (unsigned int)devid);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	printk(KERN_INFO DRVNAME ": Found %s watchdog chip, revision %d\n",
+		f71808e_names[watchdog.type],
+		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
+exit:
+	superio_exit(sioaddr);
+	return err;
+}
+
+static int __init f71808e_init(void)
+{
+	static const unsigned short addrs[] = { 0x2e, 0x4e };
+	int err = -ENODEV;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
+		err = f71808e_find(addrs[i]);
+		if (err == 0)
+			break;
+	}
+	if (i == ARRAY_SIZE(addrs))
+		return err;
+
+	return watchdog_init(addrs[i]);
+}
+
+static void __exit f71808e_exit(void)
+{
+	if (watchdog_is_running())
+	{
+		printk(KERN_WARNING DRVNAME ": Watchdog timer still running, stopping it\n");
+		watchdog_stop();
+	}
+	misc_deregister(&watchdog_miscdev);
+	unregister_reboot_notifier(&watchdog_notifier);
+}
+
+MODULE_DESCRIPTION("F71808E Watchdog Driver");
+MODULE_AUTHOR("Giel van Schijndel <me@mortis.eu>");
+MODULE_LICENSE("GPL");
+
+module_init(f71808e_init);
+module_exit(f71808e_exit);
-- 
1.6.4.4


-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new
@ 2010-03-30  9:06                                   ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-03-30  9:06 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Wim Van Sebroeck,
	Laurens Leemans, lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 23428 bytes --]

On Thu, Mar 25, 2010 at 02:17:43PM +0100, Giel van Schijndel wrote:
> Add a new watchdog driver for the Fintek F71808E Super I/O chip.

Updated patch:
 * fixes a bug where detection wouldn't function properly if a
   non-Fintek device was found (or a wrong Super I/O port chosen).
 * Add support for the F71882FG

NOTE: This patch depends on patch [1] (applied in [2]) and patch [3].

[1] https://patchwork.kernel.org/patch/89023/
[2] http://git.kernel.org/?p=linux/kernel/git/jbarnes/pci-2.6.git;a=commit;h=316607809324cc796c0809630b6ae8a768404296
[3] https://patchwork.kernel.org/patch/88235/

Patch after this line:
========================================================================
[RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E

Add a new watchdog driver for the Fintek F71808E Super I/O chip.
---
 drivers/watchdog/Kconfig       |   11 +
 drivers/watchdog/Makefile      |    1 +
 drivers/watchdog/f71808e_wdt.c |  767 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 779 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/f71808e_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 050ee14..d973105 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -366,6 +366,17 @@ config ALIM7101_WDT
 
 	  Most people will say N.
 
+config F71808E_WDT
+	tristate "Fintek F71808E Watchdog"
+	depends on X86 && EXPERIMENTAL
+	help
+	  This is the driver for the hardware watchdog on the Fintek
+	  F71808E Super I/O chip.
+
+	  You can compile this driver directly into the kernel, or use
+	  it as a module.  The module will be called f71808e_wdt.
+
+
 config GEODE_WDT
 	tristate "AMD Geode CS5535/CS5536 Watchdog"
 	depends on CS5535_MFGPT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 475c611..6f0f3d9 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
 obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
+obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
 obj-$(CONFIG_GEODE_WDT) += geodewdt.o
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
 obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
new file mode 100644
index 0000000..b0314ea
--- /dev/null
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -0,0 +1,767 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
+ *   Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com>           *
+ *   Copyright (C) 2010 Giel van Schijndel <me@mortis.eu>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+
+#define DRVNAME "f71808e_wdt"
+
+#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
+#define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
+#define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
+
+#define SIO_REG_LDSEL		0x07	/* Logical device select */
+#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
+#define SIO_REG_DEVREV		0x22	/* Device revision */
+#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE		0x30	/* Logical device enable */
+#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
+#define SIO_F71858_ID		0x0507  /* Chipset ID */
+#define SIO_F71862_ID		0x0601	/* Chipset ID */
+#define SIO_F71882_ID		0x0541	/* Chipset ID */
+#define SIO_F71889_ID		0x0723	/* Chipset ID */
+
+#define	F71882FG_REG_START		0x01
+
+#define F71808FG_REG_WDO_CONF		0xf0
+#define F71808FG_REG_WDT_CONF		0xf5
+#define F71808FG_REG_WD_TIME		0xf6
+
+#define F71808FG_FLAG_WDOUT_EN		7
+
+#define F71808FG_FLAG_WDTMOUT_STS	5
+#define F71808FG_FLAG_WD_EN		5
+#define F71808FG_FLAG_WD_PULSE		4
+#define F71808FG_FLAG_WD_UNIT		3
+
+/* Default values */
+#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
+#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
+#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
+					   watchdog signal */
+
+static unsigned short force_id;
+module_param(force_id, ushort, 0);
+MODULE_PARM_DESC(force_id, "Override the detected device ID");
+
+static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
+static int timeout = 60;	/* default timeout in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in seconds. 1<= timeout <="
+			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
+			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
+module_param(pulse_width, uint, 0);
+MODULE_PARM_DESC(pulse_width,
+	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
+			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+static unsigned int start_withtimeout;
+module_param(start_withtimeout, uint, 0);
+MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
+	" given initial timeout. Zero (default) disables this feature.");
+
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg };
+
+static const char *f71808e_names[] = {
+	"f71808fg",
+	"f71858fg",
+	"f71862fg",
+	"f71882fg",
+	"f71889fg",
+};
+
+/* Super-I/O Function prototypes */
+static inline int superio_inb(int base, int reg);
+static inline int superio_inw(int base, int reg);
+static inline void superio_outb(int base, int reg, u8 val);
+static inline void superio_set_bit(int base, int reg, int bit);
+static inline void superio_clear_bit(int base, int reg, int bit);
+static inline int superio_enter(int base);
+static inline void superio_select(int base, int ld);
+static inline void superio_exit(int base);
+
+struct watchdog_data {
+	unsigned short	sioaddr;
+	enum chips	type;
+	unsigned long	opened;
+	struct mutex	lock;
+	char		expect_close;
+	struct watchdog_info ident;
+
+	unsigned short	timeout;
+	u8		timer_val;	/* content for the wd_time register */
+	char		minutes_mode;
+	u8		pulse_val;	/* pulse width flag */
+	char		pulse_mode;	/* enable pulse output mode? */
+	char		caused_reboot;	/* last reboot was by the watchdog */
+};
+
+static struct watchdog_data watchdog = {
+	.lock = __MUTEX_INITIALIZER(watchdog.lock),
+};
+
+/* Super I/O functions */
+static inline int superio_inb(int base, int reg)
+{
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static int superio_inw(int base, int reg)
+{
+	int val;
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
+	return val;
+}
+
+static inline void superio_outb(int base, int reg, u8 val)
+{
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static inline void superio_set_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__set_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__clear_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline int superio_enter(int base)
+{
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
+	/* according to the datasheet the key must be send twice! */
+	outb(SIO_UNLOCK_KEY, base);
+	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
+}
+
+static inline void superio_select(int base, int ld)
+{
+	outb(SIO_REG_LDSEL, base);
+	outb(ld, base + 1);
+}
+
+static inline void superio_exit(int base)
+{
+	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
+}
+
+static int watchdog_set_timeout(int timeout)
+{
+	if (timeout <= 0
+	 || timeout >  max_timeout) {
+		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&watchdog.lock);
+
+	watchdog.timeout = timeout;
+	if (timeout > 0xff) {
+		watchdog.timer_val = DIV_ROUND_UP(timeout, 60);
+		watchdog.minutes_mode = true;
+	} else {
+		watchdog.timer_val = timeout;
+		watchdog.minutes_mode = false;
+	}
+
+	mutex_unlock(&watchdog.lock);
+
+	return 0;
+}
+
+static int watchdog_set_pulse_width(unsigned int pw)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+
+	if        (pw <=    1) {
+		watchdog.pulse_val = 0;
+	} else if (pw <=   25) {
+		watchdog.pulse_val = 1;
+	} else if (pw <=  125) {
+		watchdog.pulse_val = 2;
+	} else if (pw <= 5000) {
+		watchdog.pulse_val = 3;
+	} else {
+		printk(KERN_ERR DRVNAME ": pulse width out of range\n");
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+
+	watchdog.pulse_mode = pw;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_keepalive(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	if (watchdog.minutes_mode)
+		/* select minutes for timer units */
+		superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+	else
+		/* select seconds for timer units */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+
+	/* Set timer value */
+	superio_outb(watchdog.sioaddr, F71808FG_REG_WD_TIME,
+			   watchdog.timeout);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_start(void)
+{
+	/* Make sure we don't die as soon as the watchdog is enabled below */
+	int err = watchdog_keepalive();
+	if (err)
+		return err;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	/* Watchdog pin configuration */
+	switch (watchdog.type) {
+	case f71808fg:
+		/* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */
+		superio_clear_bit(watchdog.sioaddr, 0x2a, 3);
+		superio_clear_bit(watchdog.sioaddr, 0x2b, 3);
+		break;
+
+	case f71882fg:
+		/* Set pin 56 to WDTRST# */
+		superio_set_bit(watchdog.sioaddr, 0x29, 1);
+		break;
+
+	default:
+		/*
+		 * 'default' label to shut up the compiler and catch
+		 * programmer errors
+		 */
+		err = -ENODEV;
+		goto exit_superio;
+	}
+
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+	superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0);
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF,
+			F71808FG_FLAG_WDOUT_EN);
+
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	if (watchdog.pulse_mode) {
+		/* Select "pulse" output mode with given duration */
+		u8 wdt_conf = superio_inb(watchdog.sioaddr,
+				F71808FG_REG_WDT_CONF);
+
+		/* Set WD_PSWIDTH bits (1:0) */
+		wdt_conf = (wdt_conf & 0xfc) | (watchdog.pulse_val & 0x03);
+		/* Set WD_PULSE to "pulse" mode */
+		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
+
+		superio_outb(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				wdt_conf);
+	} else {
+		/* Select "level" output mode */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_PULSE);
+	}
+
+exit_superio:
+	superio_exit(watchdog.sioaddr);
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_stop(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_get_status(void)
+{
+	int status = 0;
+
+	mutex_lock(&watchdog.lock);
+	status = (watchdog.caused_reboot) ? WDIOF_CARDRESET : 0;
+	mutex_unlock(&watchdog.lock);
+
+	return status;
+}
+
+static bool watchdog_is_running(void)
+{
+	/*
+	 * if we fail to determine the watchdog's status assume it to be
+	 * running to be on the safe side
+	 */
+	bool is_running = true;
+
+	mutex_lock(&watchdog.lock);
+	if (superio_enter(watchdog.sioaddr))
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0))
+		&& (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) & F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return is_running;
+}
+
+/* /dev/watchdog api */
+
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	int err;
+
+	/* If the watchdog is alive we don't need to start it again */
+	if (test_and_set_bit(0, &watchdog.opened))
+		return -EBUSY;
+
+	err = watchdog_start();
+	if (err) {
+		clear_bit(0, &watchdog.opened);
+		return err;
+	}
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	watchdog.expect_close = 0;
+	return nonseekable_open(inode, file);
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &watchdog.opened);
+
+	if (!watchdog.expect_close) {
+		watchdog_keepalive();
+		printk(KERN_CRIT DRVNAME
+			": Unexpected close, not stopping watchdog!\n");
+	} else if (!nowayout) {
+		watchdog_stop();
+	}
+	return 0;
+}
+
+/*
+ *      watchdog_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t watchdog_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			bool expect_close = false;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				expect_close = (c == 'V');
+			}
+
+			/* Properly order writes across fork()ed processes */
+			mutex_lock(&watchdog.lock);
+			watchdog.expect_close = expect_close;
+			mutex_unlock(&watchdog.lock);
+		}
+
+		/* someone wrote to us, we should restart timer */
+		watchdog_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      watchdog_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+static long watchdog_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	int status;
+	int new_options;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &watchdog.ident,
+			sizeof(watchdog.ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		status = watchdog_get_status();
+		if (status < 0)
+			return status;
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD)
+			watchdog_stop();
+
+		if (new_options & WDIOS_ENABLECARD)
+			return watchdog_start();
+
+
+	case WDIOC_KEEPALIVE:
+		watchdog_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (watchdog_set_timeout(new_timeout))
+			return -EINVAL;
+
+		watchdog_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(watchdog.timeout, uarg.i);
+
+	default:
+		return -ENOTTY;
+
+	}
+}
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		watchdog_stop();
+	return NOTIFY_DONE;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= watchdog_open,
+	.release	= watchdog_release,
+	.write		= watchdog_write,
+	.unlocked_ioctl	= watchdog_ioctl,
+};
+
+static struct miscdevice watchdog_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &watchdog_fops,
+};
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+static int __init watchdog_init(int sioaddr)
+{
+	int wdt_conf, err = 0;
+
+	/* No need to lock watchdog.lock here because no entry points
+	 * into the module have been registered yet.
+	 */
+	watchdog.sioaddr = sioaddr;
+	watchdog.ident.options = WDIOC_SETTIMEOUT
+				| WDIOF_MAGICCLOSE
+				| WDIOF_KEEPALIVEPING;
+
+	snprintf(watchdog.ident.identity,
+		sizeof(watchdog.ident.identity), "%s watchdog",
+		f71808e_names[watchdog.type]);
+
+	err = superio_enter(sioaddr);
+	if (err)
+		return err;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF);
+	watchdog.caused_reboot = wdt_conf & F71808FG_FLAG_WDTMOUT_STS;
+
+	superio_exit(sioaddr);
+
+	err = watchdog_set_timeout(timeout);
+	if (err)
+		return err;
+	err = watchdog_set_pulse_width(pulse_width);
+	if (err)
+		return err;
+
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err)
+		return err;
+
+	err = misc_register(&watchdog_miscdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME
+			": cannot register miscdev on minor=%d\n",
+				watchdog_miscdev.minor);
+		goto exit_reboot;
+	}
+
+	if (start_withtimeout) {
+		if (start_withtimeout <= 0
+		 || start_withtimeout >  max_timeout) {
+			printk(KERN_ERR DRVNAME
+				": starting timeout out of range\n");
+			err = -EINVAL;
+			goto exit_miscdev;
+		}
+
+		err = watchdog_start();
+		if (err) {
+			printk(KERN_ERR DRVNAME
+				": cannot start watchdog timer\n");
+			goto exit_miscdev;
+		}
+
+		mutex_lock(&watchdog.lock);
+		err = superio_enter(sioaddr);
+		if (err)
+			goto exit_unlock;
+		superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+		if (start_withtimeout > 0xff) {
+			/* select minutes for timer units */
+			superio_set_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				DIV_ROUND_UP(start_withtimeout, 60));
+		} else {
+			/* select seconds for timer units */
+			superio_clear_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				start_withtimeout);
+		}
+
+		superio_exit(sioaddr);
+		mutex_unlock(&watchdog.lock);
+
+		if (nowayout)
+			__module_get(THIS_MODULE);
+
+		printk(KERN_INFO DRVNAME
+			": watchdog started with initial timeout of %u sec\n",
+			start_withtimeout);
+	}
+
+	return 0;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+exit_miscdev:
+	misc_deregister(&watchdog_miscdev);
+exit_reboot:
+	unregister_reboot_notifier(&watchdog_notifier);
+
+	return err;
+}
+
+static int __init f71808e_find(int sioaddr)
+{
+	u16 devid;
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
+
+	devid = superio_inw(sioaddr, SIO_REG_MANID);
+	if (devid != SIO_FINTEK_ID) {
+		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
+	switch (devid) {
+	case SIO_F71808_ID:
+		watchdog.type = f71808fg;
+		break;
+	case SIO_F71882_ID:
+		watchdog.type = f71882fg;
+		break;
+	case SIO_F71862_ID:
+	case SIO_F71889_ID:
+		/* These have a watchdog, though it isn't implemented (yet). */
+		err = -ENOSYS;
+		goto exit;
+	case SIO_F71858_ID:
+		/* Confirmed (by datasheet) not to have a watchdog. */
+		err = -ENODEV;
+		goto exit;
+	default:
+		printk(KERN_INFO DRVNAME ": Unrecognized Fintek device: %04x\n",
+		       (unsigned int)devid);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	printk(KERN_INFO DRVNAME ": Found %s watchdog chip, revision %d\n",
+		f71808e_names[watchdog.type],
+		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
+exit:
+	superio_exit(sioaddr);
+	return err;
+}
+
+static int __init f71808e_init(void)
+{
+	static const unsigned short addrs[] = { 0x2e, 0x4e };
+	int err = -ENODEV;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
+		err = f71808e_find(addrs[i]);
+		if (err == 0)
+			break;
+	}
+	if (i == ARRAY_SIZE(addrs))
+		return err;
+
+	return watchdog_init(addrs[i]);
+}
+
+static void __exit f71808e_exit(void)
+{
+	if (watchdog_is_running())
+	{
+		printk(KERN_WARNING DRVNAME ": Watchdog timer still running, stopping it\n");
+		watchdog_stop();
+	}
+	misc_deregister(&watchdog_miscdev);
+	unregister_reboot_notifier(&watchdog_notifier);
+}
+
+MODULE_DESCRIPTION("F71808E Watchdog Driver");
+MODULE_AUTHOR("Giel van Schijndel <me@mortis.eu>");
+MODULE_LICENSE("GPL");
+
+module_init(f71808e_init);
+module_exit(f71808e_exit);
-- 
1.6.4.4


-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/3] resource: shared I/O region support
  2010-03-29 18:29                                               ` [lm-sensors] " Alan Cox
@ 2010-04-02 20:29                                                 ` Jesse Barnes
  -1 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-04-02 20:29 UTC (permalink / raw)
  To: Alan Cox
  Cc: H. Peter Anvin, Giel van Schijndel, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 19:29:57 +0100
Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:

> > Well that does keep it simple, and with just one user that's probably
> > best.
> > 
> > But why not use the common bus driver method?  Muxing at the resource
> > level only seems to solve part of the problem...  It doesn't guarantee
> > for example that driver A does something to a shared region that breaks
> > driver B; it just makes sure they don't access the same region at the
> > same time.
> 
> The obvious reason for not doing that kind of grand over-engineering is
> that you are assuming the devices involved are remotely related. On quite
> a few systems we have a collection of superio config interfaces on random
> low ports all with their own lock/unlock rituals. They range from
> parallel devices to watchdogs and god knows what else. Right now we have
> various bits of driver code (parport is a good one) that exist on a cross
> fingers, pray and poke model. It would be nice to fix that.
> 
> For most super I/O devices the muxing is basically a glorified chip select
> line. There isn't any structure to impose over it. Where you have
> structure there are better ways to do it, but one does not exclude the
> other.

Well I'm not sure such over-engineering would be "grand", but it does
seem like overkill for the devices you're covering here.  At any rate,
the patch is in my linux-next tree, so it'll head to Linus next merge
cycle unless some big new objections arise.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/3] resource: shared I/O region support
@ 2010-04-02 20:29                                                 ` Jesse Barnes
  0 siblings, 0 replies; 159+ messages in thread
From: Jesse Barnes @ 2010-04-02 20:29 UTC (permalink / raw)
  To: Alan Cox
  Cc: H. Peter Anvin, Giel van Schijndel, Hans de Goede, Jean Delvare,
	Jonathan Cameron, Andrew Morton, Bjorn Helgaas,
	Dominik Brodowski, Laurens Leemans, lm-sensors, linux-kernel

On Mon, 29 Mar 2010 19:29:57 +0100
Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:

> > Well that does keep it simple, and with just one user that's probably
> > best.
> > 
> > But why not use the common bus driver method?  Muxing at the resource
> > level only seems to solve part of the problem...  It doesn't guarantee
> > for example that driver A does something to a shared region that breaks
> > driver B; it just makes sure they don't access the same region at the
> > same time.
> 
> The obvious reason for not doing that kind of grand over-engineering is
> that you are assuming the devices involved are remotely related. On quite
> a few systems we have a collection of superio config interfaces on random
> low ports all with their own lock/unlock rituals. They range from
> parallel devices to watchdogs and god knows what else. Right now we have
> various bits of driver code (parport is a good one) that exist on a cross
> fingers, pray and poke model. It would be nice to fix that.
> 
> For most super I/O devices the muxing is basically a glorified chip select
> line. There isn't any structure to impose over it. Where you have
> structure there are better ways to do it, but one does not exclude the
> other.

Well I'm not sure such over-engineering would be "grand", but it does
seem like overkill for the devices you're covering here.  At any rate,
the patch is in my linux-next tree, so it'll head to Linus next merge
cycle unless some big new objections arise.

-- 
Jesse Barnes, Intel Open Source Technology Center

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-03-25 13:17                               ` [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock Giel van Schijndel
@ 2010-04-25 10:35                                 ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-04-25 10:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4102 bytes --]

On Thu, Mar 25, 2010 at 02:17:42PM +0100, Giel van Schijndel wrote:
> Sleep while acquiring a resource lock on the Super I/O port. This should
> prevent collisions from causing the hardware probe to fail with -EBUSY.

Fix a bug which caused f71882fg_find() to pretend to be succesfull on
Super I/O ports which didn't have a Fintek chip attached.  This was
caused by returning 0 instead of -ENODEV, adding several 'err = -ENODEV'
statements preceding the 'goto exit' statements fixed this.

Patch follows this line:
========================================================================
Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   32 +++++++++++++++++++-------------
 1 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7857ed3..85512a7 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2239,21 +2249,15 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
 		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2280,6 +2284,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	default:
 		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
 		       (unsigned int)devid);
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2290,12 +2295,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
 		printk(KERN_WARNING DRVNAME ": Device not activated\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
 	*address = superio_inw(sioaddr, SIO_REG_ADDR);
 	if (*address == 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+		err = -ENODEV;
 		goto exit;
 	}
 	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
@@ -2306,7 +2313,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource
@ 2010-04-25 10:35                                 ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-04-25 10:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 4102 bytes --]

On Thu, Mar 25, 2010 at 02:17:42PM +0100, Giel van Schijndel wrote:
> Sleep while acquiring a resource lock on the Super I/O port. This should
> prevent collisions from causing the hardware probe to fail with -EBUSY.

Fix a bug which caused f71882fg_find() to pretend to be succesfull on
Super I/O ports which didn't have a Fintek chip attached.  This was
caused by returning 0 instead of -ENODEV, adding several 'err = -ENODEV'
statements preceding the 'goto exit' statements fixed this.

Patch follows this line:
========================================================================
Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   32 +++++++++++++++++++-------------
 1 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7857ed3..85512a7 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2239,21 +2249,15 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
 		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2280,6 +2284,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	default:
 		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
 		       (unsigned int)devid);
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2290,12 +2295,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
 		printk(KERN_WARNING DRVNAME ": Device not activated\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
 	*address = superio_inw(sioaddr, SIO_REG_ADDR);
 	if (*address == 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+		err = -ENODEV;
 		goto exit;
 	}
 	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
@@ -2306,7 +2313,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API  for F71808E and F71889
  2010-03-24 20:35                         ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
@ 2010-04-25 21:20                           ` Jim Cromie
  -1 siblings, 0 replies; 159+ messages in thread
From: Jim Cromie @ 2010-04-25 21:20 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, linux-kernel, lm-sensors, Laurens Leemans, Alan Cox

On Wed, Mar 24, 2010 at 4:35 PM, Giel van Schijndel <me@mortis.eu> wrote:
> On Wed, Mar 24, 2010 at 05:20:59PM +0100, Hans de Goede wrote:
>> On 03/24/2010 04:51 PM, Alan Cox wrote:
>>>> hold on the SIO port range. This would thus interfere with the
>>>> operation of the f71882fg driver. I.e. it would prevent the device
>>>> probing stage from working, thus preventing it from loading *after*
>>>> my in-development watchdog driver.
>>>
>>> There are two ways to deal with that really
>>>
>>> 1. Add a multi-function driver - it finds the chip and claims the
>>> port regions and then provides methods for locked access to them as
>>> well as creating other device instances that the drivers map to
>>> (probably platform devices ?) which in turn trigger the
>>> loading/binding of the relevant low level devices.
>>>
>>> 2. Fix the kernel request_resource stuff to support a sleeping non
>>> exclusive resource so request/free of regions can be used as a
>>> resource semaphore by co-operative devices.
>>>
>>> #2 is actually not hard but when I did the patch originally it then
>>> wasn't needed by the driver I had in mind for other reasons.
>>>
>>> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
>>>
>>> Maybe its worth resurrecting ?
>>
>> Or, a bit more specific solution would be to resurrect the superio
>> lock coordinator patches, which were written (but never merged) 2
>> years ago to solve exactly this problem:
>> http://lists.lm-sensors.org/pipermail/lm-sensors/2008-July/023743.html
>
> When performing some searches I find messages going back to at least
> september 2006 [1] [2]. With multiple occurences of these patches being
> "dusted off". They never got applied though, and for that (*not*
> applying them) I cannot find any reason. Is there any? Or did people
> just become uninterested and let the patches "collect dust"?
>

For my part, I started seeing difficulties in the centralized probing,
esp around the unlocking sequences; stuff thats device specific, but
wanted to be hidden in the centralized probe.  When it was just byte-sequences,
it was ok, but then too many variations presented.

> Then regarding Alan's patch. The fact that it is a *lot* simpler than
> Jim Cromie's SuperIO locks coordinator is IMHO a significant advantage
> over the latter. Furthermore, "lock coordinator" seems like a bad name
> to me, since those patches seem especially concerned with centralising
> the way that SuperIO devices are probed for. Thus if the only thing
> required is to serialize resource access I think plain-ol' locking
> (with the ability to block on the lock, rather than polling for it).
>

"coordinator" was meant to imply cooperative drivers,
though thats *always* the case, in that drivers would at least
have to check a mutex.


> [1] http://lists.lm-sensors.org/pipermail/lm-sensors/2006-June/016476.html
> [2] http://lkml.org/lkml/2006/9/14/20
>
> --
> Met vriendelijke groet,
> With kind regards,
> Giel van Schijndel
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (GNU/Linux)
>
> iEYEARECAAYFAkuqd6sACgkQZBYm/87l50K6KwCdEMTmQ2Y4k0yi8GcWOSHIeel8
> g90An3Yso3XhFqwniMyIwEa/gOSQ9uPw
> =NFuC
> -----END PGP SIGNATURE-----
>
> _______________________________________________
> lm-sensors mailing list
> lm-sensors@lm-sensors.org
> http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
>

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog
@ 2010-04-25 21:20                           ` Jim Cromie
  0 siblings, 0 replies; 159+ messages in thread
From: Jim Cromie @ 2010-04-25 21:20 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, linux-kernel, lm-sensors, Laurens Leemans, Alan Cox

On Wed, Mar 24, 2010 at 4:35 PM, Giel van Schijndel <me@mortis.eu> wrote:
> On Wed, Mar 24, 2010 at 05:20:59PM +0100, Hans de Goede wrote:
>> On 03/24/2010 04:51 PM, Alan Cox wrote:
>>>> hold on the SIO port range. This would thus interfere with the
>>>> operation of the f71882fg driver. I.e. it would prevent the device
>>>> probing stage from working, thus preventing it from loading *after*
>>>> my in-development watchdog driver.
>>>
>>> There are two ways to deal with that really
>>>
>>> 1. Add a multi-function driver - it finds the chip and claims the
>>> port regions and then provides methods for locked access to them as
>>> well as creating other device instances that the drivers map to
>>> (probably platform devices ?) which in turn trigger the
>>> loading/binding of the relevant low level devices.
>>>
>>> 2. Fix the kernel request_resource stuff to support a sleeping non
>>> exclusive resource so request/free of regions can be used as a
>>> resource semaphore by co-operative devices.
>>>
>>> #2 is actually not hard but when I did the patch originally it then
>>> wasn't needed by the driver I had in mind for other reasons.
>>>
>>> See http://groups.google.com/group/linux.kernel/msg/1425fc2aad32e6ea
>>>
>>> Maybe its worth resurrecting ?
>>
>> Or, a bit more specific solution would be to resurrect the superio
>> lock coordinator patches, which were written (but never merged) 2
>> years ago to solve exactly this problem:
>> http://lists.lm-sensors.org/pipermail/lm-sensors/2008-July/023743.html
>
> When performing some searches I find messages going back to at least
> september 2006 [1] [2]. With multiple occurences of these patches being
> "dusted off". They never got applied though, and for that (*not*
> applying them) I cannot find any reason. Is there any? Or did people
> just become uninterested and let the patches "collect dust"?
>

For my part, I started seeing difficulties in the centralized probing,
esp around the unlocking sequences; stuff thats device specific, but
wanted to be hidden in the centralized probe.  When it was just byte-sequences,
it was ok, but then too many variations presented.

> Then regarding Alan's patch. The fact that it is a *lot* simpler than
> Jim Cromie's SuperIO locks coordinator is IMHO a significant advantage
> over the latter. Furthermore, "lock coordinator" seems like a bad name
> to me, since those patches seem especially concerned with centralising
> the way that SuperIO devices are probed for. Thus if the only thing
> required is to serialize resource access I think plain-ol' locking
> (with the ability to block on the lock, rather than polling for it).
>

"coordinator" was meant to imply cooperative drivers,
though thats *always* the case, in that drivers would at least
have to check a mutex.


> [1] http://lists.lm-sensors.org/pipermail/lm-sensors/2006-June/016476.html
> [2] http://lkml.org/lkml/2006/9/14/20
>
> --
> Met vriendelijke groet,
> With kind regards,
> Giel van Schijndel
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (GNU/Linux)
>
> iEYEARECAAYFAkuqd6sACgkQZBYm/87l50K6KwCdEMTmQ2Y4k0yi8GcWOSHIeel8
> g90An3Yso3XhFqwniMyIwEa/gOSQ9uPw
> =NFuC
> -----END PGP SIGNATURE-----
>
> _______________________________________________
> lm-sensors mailing list
> lm-sensors@lm-sensors.org
> http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
>

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E
  2010-03-30  9:06                                   ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Giel van Schijndel
@ 2010-05-20  7:52                                     ` Wim Van Sebroeck
  -1 siblings, 0 replies; 159+ messages in thread
From: Wim Van Sebroeck @ 2010-05-20  7:52 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Wim Van Sebroeck,
	Laurens Leemans, lm-sensors, linux-kernel

Hi Giel,

> On Thu, Mar 25, 2010 at 02:17:43PM +0100, Giel van Schijndel wrote:
> > Add a new watchdog driver for the Fintek F71808E Super I/O chip.
> 
> Updated patch:
>  * fixes a bug where detection wouldn't function properly if a
>    non-Fintek device was found (or a wrong Super I/O port chosen).
>  * Add support for the F71882FG
> 
> NOTE: This patch depends on patch [1] (applied in [2]) and patch [3].
> 
> [1] https://patchwork.kernel.org/patch/89023/
> [2] http://git.kernel.org/?p=linux/kernel/git/jbarnes/pci-2.6.git;a=commit;h=316607809324cc796c0809630b6ae8a768404296
> [3] https://patchwork.kernel.org/patch/88235/

Driver looks OK to me. Can't apply it before the I/O resource sharing is in place.
How do you want to proceed?

Kind regards,
Wim.


^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new
@ 2010-05-20  7:52                                     ` Wim Van Sebroeck
  0 siblings, 0 replies; 159+ messages in thread
From: Wim Van Sebroeck @ 2010-05-20  7:52 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Wim Van Sebroeck,
	Laurens Leemans, lm-sensors, linux-kernel

Hi Giel,

> On Thu, Mar 25, 2010 at 02:17:43PM +0100, Giel van Schijndel wrote:
> > Add a new watchdog driver for the Fintek F71808E Super I/O chip.
> 
> Updated patch:
>  * fixes a bug where detection wouldn't function properly if a
>    non-Fintek device was found (or a wrong Super I/O port chosen).
>  * Add support for the F71882FG
> 
> NOTE: This patch depends on patch [1] (applied in [2]) and patch [3].
> 
> [1] https://patchwork.kernel.org/patch/89023/
> [2] http://git.kernel.org/?p=linux/kernel/git/jbarnes/pci-2.6.git;a=commit;h16607809324cc796c0809630b6ae8a768404296
> [3] https://patchwork.kernel.org/patch/88235/

Driver looks OK to me. Can't apply it before the I/O resource sharing is in place.
How do you want to proceed?

Kind regards,
Wim.


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E
  2010-05-20  7:52                                     ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Wim Van Sebroeck
@ 2010-05-25 21:08                                       ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-05-25 21:08 UTC (permalink / raw)
  To: Wim Van Sebroeck
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1035 bytes --]

On Thu, May 20, 2010 at 09:52:29AM +0200, Wim Van Sebroeck wrote:
>> On Thu, Mar 25, 2010 at 02:17:43PM +0100, Giel van Schijndel wrote:
>> > Add a new watchdog driver for the Fintek F71808E Super I/O chip.
>> 
>> Updated patch:
>>  * fixes a bug where detection wouldn't function properly if a
>>    non-Fintek device was found (or a wrong Super I/O port chosen).
>>  * Add support for the F71882FG
>> 
>> NOTE: This patch depends on patch [1] (applied in [2]) and patch [3].
>> 
>> [1] https://patchwork.kernel.org/patch/89023/
>> [2] http://git.kernel.org/?p=linux/kernel/git/jbarnes/pci-2.6.git;a=commit;h=316607809324cc796c0809630b6ae8a768404296
>> [3] https://patchwork.kernel.org/patch/88235/
> 
> Driver looks OK to me. Can't apply it before the I/O resource sharing
> is in place.  How do you want to proceed?

I would think applying it to watchdog-next to apply it for the next
kernel release (similar to Jean Delvare's linux-next).

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new
@ 2010-05-25 21:08                                       ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-05-25 21:08 UTC (permalink / raw)
  To: Wim Van Sebroeck
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1035 bytes --]

On Thu, May 20, 2010 at 09:52:29AM +0200, Wim Van Sebroeck wrote:
>> On Thu, Mar 25, 2010 at 02:17:43PM +0100, Giel van Schijndel wrote:
>> > Add a new watchdog driver for the Fintek F71808E Super I/O chip.
>> 
>> Updated patch:
>>  * fixes a bug where detection wouldn't function properly if a
>>    non-Fintek device was found (or a wrong Super I/O port chosen).
>>  * Add support for the F71882FG
>> 
>> NOTE: This patch depends on patch [1] (applied in [2]) and patch [3].
>> 
>> [1] https://patchwork.kernel.org/patch/89023/
>> [2] http://git.kernel.org/?p=linux/kernel/git/jbarnes/pci-2.6.git;a=commit;h=316607809324cc796c0809630b6ae8a768404296
>> [3] https://patchwork.kernel.org/patch/88235/
> 
> Driver looks OK to me. Can't apply it before the I/O resource sharing
> is in place.  How do you want to proceed?

I would think applying it to watchdog-next to apply it for the next
kernel release (similar to Jean Delvare's linux-next).

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E
  2010-05-25 21:08                                       ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Giel van Schijndel
@ 2010-05-26  7:38                                         ` Wim Van Sebroeck
  -1 siblings, 0 replies; 159+ messages in thread
From: Wim Van Sebroeck @ 2010-05-26  7:38 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

Hi Giel,

> > Driver looks OK to me. Can't apply it before the I/O resource sharing
> > is in place.  How do you want to proceed?
> 
> I would think applying it to watchdog-next to apply it for the next
> kernel release (similar to Jean Delvare's linux-next).

Will add it after 2.6.35-rc1 is out then.

Kind regards,
Wim.


^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new
@ 2010-05-26  7:38                                         ` Wim Van Sebroeck
  0 siblings, 0 replies; 159+ messages in thread
From: Wim Van Sebroeck @ 2010-05-26  7:38 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

Hi Giel,

> > Driver looks OK to me. Can't apply it before the I/O resource sharing
> > is in place.  How do you want to proceed?
> 
> I would think applying it to watchdog-next to apply it for the next
> kernel release (similar to Jean Delvare's linux-next).

Will add it after 2.6.35-rc1 is out then.

Kind regards,
Wim.


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-04-25 10:35                                 ` [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource Giel van Schijndel
@ 2010-07-31 21:21                                   ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-07-31 21:21 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1083 bytes --]

On Sun, Apr 25, 2010 at 12:35:40 +0200, Giel van Schijndel wrote:
> On Thu, Mar 25, 2010 at 14:17:42 +0100, Giel van Schijndel wrote:
>> Sleep while acquiring a resource lock on the Super I/O port. This
>> should prevent collisions from causing the hardware probe to fail
>> with -EBUSY.
> 
> Fix a bug which caused f71882fg_find() to pretend to be succesfull on
> Super I/O ports which didn't have a Fintek chip attached.  This was
> caused by returning 0 instead of -ENODEV, adding several 'err =
> -ENODEV' statements preceding the 'goto exit' statements fixed this.
> 
> Patch follows this line:
> ========================================================================
> Sleep while acquiring a resource lock on the Super I/O port. This
> should prevent collisions from causing the hardware probe to fail with
> -EBUSY.
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>

All of this patch's dependencies now reside in mainline, so I'd like to
"renew" the request for applying it.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource
@ 2010-07-31 21:21                                   ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-07-31 21:21 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1083 bytes --]

On Sun, Apr 25, 2010 at 12:35:40 +0200, Giel van Schijndel wrote:
> On Thu, Mar 25, 2010 at 14:17:42 +0100, Giel van Schijndel wrote:
>> Sleep while acquiring a resource lock on the Super I/O port. This
>> should prevent collisions from causing the hardware probe to fail
>> with -EBUSY.
> 
> Fix a bug which caused f71882fg_find() to pretend to be succesfull on
> Super I/O ports which didn't have a Fintek chip attached.  This was
> caused by returning 0 instead of -ENODEV, adding several 'err =
> -ENODEV' statements preceding the 'goto exit' statements fixed this.
> 
> Patch follows this line:
> ========================================================================
> Sleep while acquiring a resource lock on the Super I/O port. This
> should prevent collisions from causing the hardware probe to fail with
> -EBUSY.
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>

All of this patch's dependencies now reside in mainline, so I'd like to
"renew" the request for applying it.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E
  2010-05-26  7:38                                         ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Wim Van Sebroeck
@ 2010-07-31 21:36                                           ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-07-31 21:36 UTC (permalink / raw)
  To: Wim Van Sebroeck
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 514 bytes --]

On Wed, May 26, 2010 at 09:38:43 +0200, Wim Van Sebroeck wrote:
>>> Driver looks OK to me. Can't apply it before the I/O resource
>>> sharing is in place.  How do you want to proceed?
>> 
>> I would think applying it to watchdog-next to apply it for the next
>> kernel release (similar to Jean Delvare's linux-next).
> 
> Will add it after 2.6.35-rc1 is out then.

Sending a reminder, as 2.6.35-rc1 has been tagged for a while now.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new
@ 2010-07-31 21:36                                           ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-07-31 21:36 UTC (permalink / raw)
  To: Wim Van Sebroeck
  Cc: Hans de Goede, Jean Delvare, Jonathan Cameron, Laurens Leemans,
	lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 514 bytes --]

On Wed, May 26, 2010 at 09:38:43 +0200, Wim Van Sebroeck wrote:
>>> Driver looks OK to me. Can't apply it before the I/O resource
>>> sharing is in place.  How do you want to proceed?
>> 
>> I would think applying it to watchdog-next to apply it for the next
>> kernel release (similar to Jean Delvare's linux-next).
> 
> Will add it after 2.6.35-rc1 is out then.

Sending a reminder, as 2.6.35-rc1 has been tagged for a while now.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-03-24 10:31           ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Hans de Goede
@ 2010-07-31 23:31             ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-07-31 23:31 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2752 bytes --]

On Wed, Mar 24, 2010 at 11:31:40 +0100, Hans de Goede wrote:
> On 03/24/2010 10:23, Giel van Schijndel wrote:
>> On Wed, Mar 24, 2010 at 09:25:08 +0100, Hans de Goede wrote:
>>> See comments inline.
>>>
>>> On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
>>>> Allow device probing to recognise the Fintek F71808E.
>>>> 
>>>> Sysfs interface:
>>>>    * Fan/pwm control is the same as for F71889FG
>>>>    * Temperature and voltage sensor handling is largely the same as for
>>>>      the F71889FG
>>>>     - Has one temperature sensor less (doesn't have temp3)
>>>>     - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>>>       what in7_input refers for F71889FG)
>>>> 
>>>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>>>> such that it can largely be reused.
>>>>---
>>>>   Documentation/hwmon/f71882fg |    4 ++
>>>>   drivers/hwmon/Kconfig        |    6 ++--
>>>>   drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>>>>   3 files changed, 79 insertions(+), 11 deletions(-)
>>>>
>>>> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
>>>> index 25e1cad..b290b87 100644
>>>> --- a/drivers/hwmon/f71882fg.c
>>>> +++ b/drivers/hwmon/f71882fg.c
>>>> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>>>> ... snip ...
>>>> +			/* fall through! */
>>>
>>> Ugh, please don't fall through, and then have an if below to only do
>>> some parts of the case falling through. This is quite confusing at
>>> first I thought your code was buggy I had to read it twice to notice
>>> the if. Instead just duplicate the following lines:
>>>> +			err = f71882fg_create_sysfs_files(pdev,
>>>> +					fxxxx_temp_attr,
>>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>> In the f71862fg case, end the f71862fg case with a break and remove
>>> the if test from the f71808fg case.
>>>
>>>>+		case f71808fg:
>>>>+			if (data->type == f71808fg) {
>>>>+				err = f71882fg_create_sysfs_files(pdev,
>>>>+						f71808_in_attr,
>>>>+						ARRAY_SIZE(f71808_in_attr));
>>>>+				if (err)
>>>>+					goto exit_unregister_sysfs;
>>>>+			}
>>>>+			err = f71882fg_create_sysfs_files(pdev,
>>>>+					fxxxx_temp_attr,
>>>>+					ARRAY_SIZE(fxxxx_temp_attr));
>>>> ... snip ...
>>
>> Ack. New and improved patch follows this line.
>> =====================================================================
>> hwmon: f71882fg: Add support for the Fintek F71808E
> 
> This new version looks good to me:
> Acked-by: Hans de Goede <hdegoede@redhat.com>

Thanks.  Anyone else I need to poke in order to set this on track to
mainline?

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the
@ 2010-07-31 23:31             ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-07-31 23:31 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 2752 bytes --]

On Wed, Mar 24, 2010 at 11:31:40 +0100, Hans de Goede wrote:
> On 03/24/2010 10:23, Giel van Schijndel wrote:
>> On Wed, Mar 24, 2010 at 09:25:08 +0100, Hans de Goede wrote:
>>> See comments inline.
>>>
>>> On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
>>>> Allow device probing to recognise the Fintek F71808E.
>>>> 
>>>> Sysfs interface:
>>>>    * Fan/pwm control is the same as for F71889FG
>>>>    * Temperature and voltage sensor handling is largely the same as for
>>>>      the F71889FG
>>>>     - Has one temperature sensor less (doesn't have temp3)
>>>>     - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>>>       what in7_input refers for F71889FG)
>>>> 
>>>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>>>> such that it can largely be reused.
>>>>---
>>>>   Documentation/hwmon/f71882fg |    4 ++
>>>>   drivers/hwmon/Kconfig        |    6 ++--
>>>>   drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>>>>   3 files changed, 79 insertions(+), 11 deletions(-)
>>>>
>>>> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
>>>> index 25e1cad..b290b87 100644
>>>> --- a/drivers/hwmon/f71882fg.c
>>>> +++ b/drivers/hwmon/f71882fg.c
>>>> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>>>> ... snip ...
>>>> +			/* fall through! */
>>>
>>> Ugh, please don't fall through, and then have an if below to only do
>>> some parts of the case falling through. This is quite confusing at
>>> first I thought your code was buggy I had to read it twice to notice
>>> the if. Instead just duplicate the following lines:
>>>> +			err = f71882fg_create_sysfs_files(pdev,
>>>> +					fxxxx_temp_attr,
>>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>> In the f71862fg case, end the f71862fg case with a break and remove
>>> the if test from the f71808fg case.
>>>
>>>>+		case f71808fg:
>>>>+			if (data->type == f71808fg) {
>>>>+				err = f71882fg_create_sysfs_files(pdev,
>>>>+						f71808_in_attr,
>>>>+						ARRAY_SIZE(f71808_in_attr));
>>>>+				if (err)
>>>>+					goto exit_unregister_sysfs;
>>>>+			}
>>>>+			err = f71882fg_create_sysfs_files(pdev,
>>>>+					fxxxx_temp_attr,
>>>>+					ARRAY_SIZE(fxxxx_temp_attr));
>>>> ... snip ...
>>
>> Ack. New and improved patch follows this line.
>> =====================================================================
>> hwmon: f71882fg: Add support for the Fintek F71808E
> 
> This new version looks good to me:
> Acked-by: Hans de Goede <hdegoede@redhat.com>

Thanks.  Anyone else I need to poke in order to set this on track to
mainline?

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-07-31 23:31             ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Giel van Schijndel
@ 2010-08-01  6:12               ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-01  6:12 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

On 08/01/2010 01:31 AM, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 11:31:40 +0100, Hans de Goede wrote:
>> On 03/24/2010 10:23, Giel van Schijndel wrote:
>>> On Wed, Mar 24, 2010 at 09:25:08 +0100, Hans de Goede wrote:
>>>> See comments inline.
>>>>
>>>> On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
>>>>> Allow device probing to recognise the Fintek F71808E.
>>>>>
>>>>> Sysfs interface:
>>>>>     * Fan/pwm control is the same as for F71889FG
>>>>>     * Temperature and voltage sensor handling is largely the same as for
>>>>>       the F71889FG
>>>>>      - Has one temperature sensor less (doesn't have temp3)
>>>>>      - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>>>>        what in7_input refers for F71889FG)
>>>>>
>>>>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>>>>> such that it can largely be reused.
>>>>> ---
>>>>>    Documentation/hwmon/f71882fg |    4 ++
>>>>>    drivers/hwmon/Kconfig        |    6 ++--
>>>>>    drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>>>>>    3 files changed, 79 insertions(+), 11 deletions(-)
>>>>>
>>>>> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
>>>>> index 25e1cad..b290b87 100644
>>>>> --- a/drivers/hwmon/f71882fg.c
>>>>> +++ b/drivers/hwmon/f71882fg.c
>>>>> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>>>>> ... snip ...
>>>>> +			/* fall through! */
>>>>
>>>> Ugh, please don't fall through, and then have an if below to only do
>>>> some parts of the case falling through. This is quite confusing at
>>>> first I thought your code was buggy I had to read it twice to notice
>>>> the if. Instead just duplicate the following lines:
>>>>> +			err = f71882fg_create_sysfs_files(pdev,
>>>>> +					fxxxx_temp_attr,
>>>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>>> In the f71862fg case, end the f71862fg case with a break and remove
>>>> the if test from the f71808fg case.
>>>>
>>>>> +		case f71808fg:
>>>>> +			if (data->type == f71808fg) {
>>>>> +				err = f71882fg_create_sysfs_files(pdev,
>>>>> +						f71808_in_attr,
>>>>> +						ARRAY_SIZE(f71808_in_attr));
>>>>> +				if (err)
>>>>> +					goto exit_unregister_sysfs;
>>>>> +			}
>>>>> +			err = f71882fg_create_sysfs_files(pdev,
>>>>> +					fxxxx_temp_attr,
>>>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>>>> ... snip ...
>>>
>>> Ack. New and improved patch follows this line.
>>> =====================================================================
>>> hwmon: f71882fg: Add support for the Fintek F71808E
>>
>> This new version looks good to me:
>> Acked-by: Hans de Goede<hdegoede@redhat.com>
>
> Thanks.  Anyone else I need to poke in order to set this on track to
> mainline?
>

No,

Jean should have picked this up, I guess it has fallen through the cracks.

I think it is probably best if you resend this patch and the watchdog patches
re-based against the latest upstream rc, then I'll re-review them and ack
them and Jean can then put them into his tree.

Thanks & Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the
@ 2010-08-01  6:12               ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-01  6:12 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Jean Delvare, Jonathan Cameron, Laurens Leemans, lm-sensors,
	linux-kernel

Hi,

On 08/01/2010 01:31 AM, Giel van Schijndel wrote:
> On Wed, Mar 24, 2010 at 11:31:40 +0100, Hans de Goede wrote:
>> On 03/24/2010 10:23, Giel van Schijndel wrote:
>>> On Wed, Mar 24, 2010 at 09:25:08 +0100, Hans de Goede wrote:
>>>> See comments inline.
>>>>
>>>> On 03/24/2010 12:12 AM, Giel van Schijndel wrote:
>>>>> Allow device probing to recognise the Fintek F71808E.
>>>>>
>>>>> Sysfs interface:
>>>>>     * Fan/pwm control is the same as for F71889FG
>>>>>     * Temperature and voltage sensor handling is largely the same as for
>>>>>       the F71889FG
>>>>>      - Has one temperature sensor less (doesn't have temp3)
>>>>>      - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>>>>        what in7_input refers for F71889FG)
>>>>>
>>>>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>>>>> such that it can largely be reused.
>>>>> ---
>>>>>    Documentation/hwmon/f71882fg |    4 ++
>>>>>    drivers/hwmon/Kconfig        |    6 ++--
>>>>>    drivers/hwmon/f71882fg.c     |   80 +++++++++++++++++++++++++++++++++++++----
>>>>>    3 files changed, 79 insertions(+), 11 deletions(-)
>>>>>
>>>>> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
>>>>> index 25e1cad..b290b87 100644
>>>>> --- a/drivers/hwmon/f71882fg.c
>>>>> +++ b/drivers/hwmon/f71882fg.c
>>>>> @@ -1974,8 +2002,27 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
>>>>> ... snip ...
>>>>> +			/* fall through! */
>>>>
>>>> Ugh, please don't fall through, and then have an if below to only do
>>>> some parts of the case falling through. This is quite confusing at
>>>> first I thought your code was buggy I had to read it twice to notice
>>>> the if. Instead just duplicate the following lines:
>>>>> +			err = f71882fg_create_sysfs_files(pdev,
>>>>> +					fxxxx_temp_attr,
>>>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>>> In the f71862fg case, end the f71862fg case with a break and remove
>>>> the if test from the f71808fg case.
>>>>
>>>>> +		case f71808fg:
>>>>> +			if (data->type = f71808fg) {
>>>>> +				err = f71882fg_create_sysfs_files(pdev,
>>>>> +						f71808_in_attr,
>>>>> +						ARRAY_SIZE(f71808_in_attr));
>>>>> +				if (err)
>>>>> +					goto exit_unregister_sysfs;
>>>>> +			}
>>>>> +			err = f71882fg_create_sysfs_files(pdev,
>>>>> +					fxxxx_temp_attr,
>>>>> +					ARRAY_SIZE(fxxxx_temp_attr));
>>>>> ... snip ...
>>>
>>> Ack. New and improved patch follows this line.
>>> ==================================>>> hwmon: f71882fg: Add support for the Fintek F71808E
>>
>> This new version looks good to me:
>> Acked-by: Hans de Goede<hdegoede@redhat.com>
>
> Thanks.  Anyone else I need to poke in order to set this on track to
> mainline?
>

No,

Jean should have picked this up, I guess it has fallen through the cracks.

I think it is probably best if you resend this patch and the watchdog patches
re-based against the latest upstream rc, then I'll re-review them and ack
them and Jean can then put them into his tree.

Thanks & Regards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-01  6:12               ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Hans de Goede
@ 2010-08-01 13:22                 ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-01 13:22 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Wim Van Sebroeck,
	Laurens Leemans, lm-sensors, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1031 bytes --]

On Sun, Aug 01, 2010 at 08:12:40 +0200, Hans de Goede wrote:
> On 08/01/2010 01:31 AM, Giel van Schijndel wrote:
>> On Wed, Mar 24, 2010 at 11:31:40 +0100, Hans de Goede wrote:
>>> On 03/24/2010 10:23, Giel van Schijndel wrote:
>>>> Ack. New and improved patch follows this line.
>>>> ===================================================================
>>>> hwmon: f71882fg: Add support for the Fintek F71808E
>>>
>>> This new version looks good to me:
>>> Acked-by: Hans de Goede<hdegoede@redhat.com>
>>
>> Thanks.  Anyone else I need to poke in order to set this on track to
>> mainline?
> 
> No,
> 
> Jean should have picked this up, I guess it has fallen through the cracks.
> 
> I think it is probably best if you resend this patch and the watchdog
> patches re-based against the latest upstream rc, then I'll re-review
> them and ack them and Jean can then put them into his tree.

Ack.  I'll resend them as replies to this mail.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the
@ 2010-08-01 13:22                 ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-01 13:22 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Jean Delvare, Jonathan Cameron, Wim Van Sebroeck,
	Laurens Leemans, lm-sensors, linux-kernel


[-- Attachment #1.1: Type: text/plain, Size: 1031 bytes --]

On Sun, Aug 01, 2010 at 08:12:40 +0200, Hans de Goede wrote:
> On 08/01/2010 01:31 AM, Giel van Schijndel wrote:
>> On Wed, Mar 24, 2010 at 11:31:40 +0100, Hans de Goede wrote:
>>> On 03/24/2010 10:23, Giel van Schijndel wrote:
>>>> Ack. New and improved patch follows this line.
>>>> ===================================================================
>>>> hwmon: f71882fg: Add support for the Fintek F71808E
>>>
>>> This new version looks good to me:
>>> Acked-by: Hans de Goede<hdegoede@redhat.com>
>>
>> Thanks.  Anyone else I need to poke in order to set this on track to
>> mainline?
> 
> No,
> 
> Jean should have picked this up, I guess it has fallen through the cracks.
> 
> I think it is probably best if you resend this patch and the watchdog
> patches re-based against the latest upstream rc, then I'll re-review
> them and ack them and Jean can then put them into his tree.

Ack.  I'll resend them as replies to this mail.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-01 13:22                 ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Giel van Schijndel
@ 2010-08-01 13:30                   ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-01 13:30 UTC (permalink / raw)
  Cc: Laurens Leemans, Jonathan Cameron, Giel van Schijndel,
	Randy Dunlap, Hans de Goede, Jean Delvare, Andrew Morton,
	Mark Brown, Samuel Ortiz, lm-sensors, linux-kernel, linux-doc

Allow device probing to recognise the Fintek F71808E.

Sysfs interface:
 * Fan/pwm control is the same as for F71889FG
 * Temperature and voltage sensor handling is largely the same as for
   the F71889FG
  - Has one temperature sensor less (doesn't have temp3)
  - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
    what in7_input refers for F71889FG)

For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
such that it can largely be reused.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 Documentation/hwmon/f71882fg |    4 ++
 drivers/hwmon/Kconfig        |    6 ++--
 drivers/hwmon/f71882fg.c     |   83 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index a7952c2..1a07fd6 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -2,6 +2,10 @@ Kernel driver f71882fg
 ======================
 
 Supported chips:
+  * Fintek F71808E
+    Prefix: 'f71808fg'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71858FG
     Prefix: 'f71858fg'
     Addresses scanned: none, address read from Super I/O config space
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e19cf8e..7d0beac 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -332,11 +332,11 @@ config SENSORS_F71805F
 	  will be called f71805f.
 
 config SENSORS_F71882FG
-	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
+	tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
 	depends on EXPERIMENTAL
 	help
-	  If you say yes here you get support for hardware monitoring
-	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+	  If you say yes here you get support for hardware monitoring features
+	  of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
 	  F71889FG and F8000 Super-I/O chips.
 
 	  This driver can also be built as a module.  If so, the module
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index f4d2279..7857ed3 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -45,6 +45,7 @@
 #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
 
 #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
@@ -96,9 +97,10 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
+	"f71808fg",
 	"f71858fg",
 	"f71862fg",
 	"f71882fg",
@@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 };
 
-/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
-static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
+/* In attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
 	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
 	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* In attr for the f71808fg */
+static struct sensor_device_attribute_2 f71808_in_attr[] = {
+	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
+	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
+	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
+	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
+	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
+	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
+	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
+	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
 	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
 	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 1),
@@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 		store_temp_beep, 0, 6),
 	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
 	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
+};
+
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 f71862_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
 	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 3),
@@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
 				data->temp_type[1] = 6;
 				break;
 			}
+		} else if (data->type == f71808fg) {
+			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
+			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
+
 		} else {
 			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
 			if ((reg2 & 0x03) == 0x01)
@@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
 
 	val /= 1000;
 
-	if (data->type == f71889fg)
+	if (data->type == f71889fg
+	 || data->type == f71808fg)
 		val = SENSORS_LIMIT(val, -128, 127);
 	else
 		val = SENSORS_LIMIT(val, 0, 127);
@@ -1974,8 +2002,28 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
+			break;
+		case f71808fg:
+			err = f71882fg_create_sysfs_files(pdev,
+					f71808_in_attr,
+					ARRAY_SIZE(f71808_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
@@ -2002,6 +2050,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 		case f71862fg:
 			err = (data->pwm_enable & 0x15) != 0x15;
 			break;
+		case f71808fg:
 		case f71882fg:
 		case f71889fg:
 			err = 0;
@@ -2047,6 +2096,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 					f8000_auto_pwm_attr,
 					ARRAY_SIZE(f8000_auto_pwm_attr));
 			break;
+		case f71808fg:
 		case f71889fg:
 			for (i = 0; i < nr_fans; i++) {
 				data->pwm_auto_point_mapping[i] =
@@ -2126,8 +2176,22 @@ static int f71882fg_remove(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			f71882fg_remove_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
+			break;
+		case f71808fg:
+			f71882fg_remove_sysfs_files(pdev,
+					f71808_in_attr,
+					ARRAY_SIZE(f71808_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			f71882fg_remove_sysfs_files(pdev,
@@ -2195,6 +2259,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
 	switch (devid) {
+	case SIO_F71808_ID:
+		sio_data->type = f71808fg;
+		break;
 	case SIO_F71858_ID:
 		sio_data->type = f71858fg;
 		break;
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Fintek
@ 2010-08-01 13:30                   ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-01 13:30 UTC (permalink / raw)
  Cc: Laurens Leemans, Jonathan Cameron, Giel van Schijndel,
	Randy Dunlap, Hans de Goede, Jean Delvare, Andrew Morton,
	Mark Brown, Samuel Ortiz, lm-sensors, linux-kernel, linux-doc

Allow device probing to recognise the Fintek F71808E.

Sysfs interface:
 * Fan/pwm control is the same as for F71889FG
 * Temperature and voltage sensor handling is largely the same as for
   the F71889FG
  - Has one temperature sensor less (doesn't have temp3)
  - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
    what in7_input refers for F71889FG)

For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
such that it can largely be reused.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 Documentation/hwmon/f71882fg |    4 ++
 drivers/hwmon/Kconfig        |    6 ++--
 drivers/hwmon/f71882fg.c     |   83 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
index a7952c2..1a07fd6 100644
--- a/Documentation/hwmon/f71882fg
+++ b/Documentation/hwmon/f71882fg
@@ -2,6 +2,10 @@ Kernel driver f71882fg
 ===========
 
 Supported chips:
+  * Fintek F71808E
+    Prefix: 'f71808fg'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71858FG
     Prefix: 'f71858fg'
     Addresses scanned: none, address read from Super I/O config space
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e19cf8e..7d0beac 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -332,11 +332,11 @@ config SENSORS_F71805F
 	  will be called f71805f.
 
 config SENSORS_F71882FG
-	tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000"
+	tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000"
 	depends on EXPERIMENTAL
 	help
-	  If you say yes here you get support for hardware monitoring
-	  features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
+	  If you say yes here you get support for hardware monitoring features
+	  of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG,
 	  F71889FG and F8000 Super-I/O chips.
 
 	  This driver can also be built as a module.  If so, the module
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index f4d2279..7857ed3 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -45,6 +45,7 @@
 #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
 
 #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
@@ -96,9 +97,10 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
 
 static const char *f71882fg_names[] = {
+	"f71808fg",
 	"f71858fg",
 	"f71862fg",
 	"f71882fg",
@@ -306,8 +308,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
 };
 
-/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
-static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
+/* In attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
 	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
 	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
 	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
@@ -317,6 +319,22 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
 	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
 	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* In attr for the f71808fg */
+static struct sensor_device_attribute_2 f71808_in_attr[] = {
+	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
+	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
+	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
+	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
+	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
+	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
+	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
+	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
+};
+
+/* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
 	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
 	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 1),
@@ -355,6 +373,10 @@ static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = {
 		store_temp_beep, 0, 6),
 	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
 	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
+};
+
+/* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
+static struct sensor_device_attribute_2 f71862_temp_attr[] = {
 	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
 	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
 		store_temp_max, 0, 3),
@@ -989,6 +1011,11 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
 				data->temp_type[1] = 6;
 				break;
 			}
+		} else if (data->type = f71808fg) {
+			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
+			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
+			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
+
 		} else {
 			reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
 			if ((reg2 & 0x03) = 0x01)
@@ -1871,7 +1898,8 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
 
 	val /= 1000;
 
-	if (data->type = f71889fg)
+	if (data->type = f71889fg
+	 || data->type = f71808fg)
 		val = SENSORS_LIMIT(val, -128, 127);
 	else
 		val = SENSORS_LIMIT(val, 0, 127);
@@ -1974,8 +2002,28 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
+			break;
+		case f71808fg:
+			err = f71882fg_create_sysfs_files(pdev,
+					f71808_in_attr,
+					ARRAY_SIZE(f71808_in_attr));
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			err = f71882fg_create_sysfs_files(pdev,
@@ -2002,6 +2050,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 		case f71862fg:
 			err = (data->pwm_enable & 0x15) != 0x15;
 			break;
+		case f71808fg:
 		case f71882fg:
 		case f71889fg:
 			err = 0;
@@ -2047,6 +2096,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 					f8000_auto_pwm_attr,
 					ARRAY_SIZE(f8000_auto_pwm_attr));
 			break;
+		case f71808fg:
 		case f71889fg:
 			for (i = 0; i < nr_fans; i++) {
 				data->pwm_auto_point_mapping[i] @@ -2126,8 +2176,22 @@ static int f71882fg_remove(struct platform_device *pdev)
 			/* fall through! */
 		case f71862fg:
 			f71882fg_remove_sysfs_files(pdev,
-					fxxxx_in_temp_attr,
-					ARRAY_SIZE(fxxxx_in_temp_attr));
+					f71862_temp_attr,
+					ARRAY_SIZE(f71862_temp_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_in_attr,
+					ARRAY_SIZE(fxxxx_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
+			break;
+		case f71808fg:
+			f71882fg_remove_sysfs_files(pdev,
+					f71808_in_attr,
+					ARRAY_SIZE(f71808_in_attr));
+			f71882fg_remove_sysfs_files(pdev,
+					fxxxx_temp_attr,
+					ARRAY_SIZE(fxxxx_temp_attr));
 			break;
 		case f8000:
 			f71882fg_remove_sysfs_files(pdev,
@@ -2195,6 +2259,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
 	switch (devid) {
+	case SIO_F71808_ID:
+		sio_data->type = f71808fg;
+		break;
 	case SIO_F71858_ID:
 		sio_data->type = f71858fg;
 		break;
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-08-01 13:22                 ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Giel van Schijndel
@ 2010-08-01 13:30                   ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-01 13:30 UTC (permalink / raw)
  Cc: Laurens Leemans, Jonathan Cameron, Giel van Schijndel,
	Jean Delvare, Hans de Goede, lm-sensors, linux-kernel

Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   32 +++++++++++++++++++-------------
 1 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7857ed3..267cb92 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2239,21 +2249,15 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
 		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2280,6 +2284,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	default:
 		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
 		       (unsigned int)devid);
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2290,12 +2295,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
 		printk(KERN_WARNING DRVNAME ": Device not activated\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
 	*address = superio_inw(sioaddr, SIO_REG_ADDR);
 	if (*address == 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+		err = -ENODEV;
 		goto exit;
 	}
 	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
@@ -2306,7 +2313,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock
@ 2010-08-01 13:30                   ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-01 13:30 UTC (permalink / raw)
  Cc: Laurens Leemans, Jonathan Cameron, Giel van Schijndel,
	Jean Delvare, Hans de Goede, lm-sensors, linux-kernel

Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   32 +++++++++++++++++++-------------
 1 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 7857ed3..267cb92 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2239,21 +2249,15 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
 		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2280,6 +2284,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	default:
 		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
 		       (unsigned int)devid);
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2290,12 +2295,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
 		printk(KERN_WARNING DRVNAME ": Device not activated\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
 	*address = superio_inw(sioaddr, SIO_REG_ADDR);
 	if (*address = 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+		err = -ENODEV;
 		goto exit;
 	}
 	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
@@ -2306,7 +2313,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH 2/2] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E and F71882FG
  2010-08-01 13:30                   ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock Giel van Schijndel
@ 2010-08-01 13:30                     ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-01 13:30 UTC (permalink / raw)
  Cc: Laurens Leemans, Jonathan Cameron, Giel van Schijndel,
	Wim Van Sebroeck, Andrew Morton, Russell King, Tony Lindgren,
	Marc Zyngier, Thierry Reding, linux-watchdog, linux-kernel

Add a new watchdog driver for the Fintek F71808E and F71882FG Super I/O
controllers.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/watchdog/Kconfig       |   11 +
 drivers/watchdog/Makefile      |    1 +
 drivers/watchdog/f71808e_wdt.c |  768 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 780 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/f71808e_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index afcfacc..edfd57d 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -401,6 +401,17 @@ config ALIM7101_WDT
 
 	  Most people will say N.
 
+config F71808E_WDT
+	tristate "Fintek F71808E and F71882FG Watchdog"
+	depends on X86 && EXPERIMENTAL
+	help
+	  This is the driver for the hardware watchdog on the Fintek
+	  F71808E and F71882FG Super I/O controllers.
+
+	  You can compile this driver directly into the kernel, or use
+	  it as a module.  The module will be called f71808e_wdt.
+
+
 config GEODE_WDT
 	tristate "AMD Geode CS5535/CS5536 Watchdog"
 	depends on CS5535_MFGPT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 72f3e20..9e3d616 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
 obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
+obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
 obj-$(CONFIG_GEODE_WDT) += geodewdt.o
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
 obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
new file mode 100644
index 0000000..7e5c266
--- /dev/null
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -0,0 +1,768 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
+ *   Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com>           *
+ *   Copyright (C) 2010 Giel van Schijndel <me@mortis.eu>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+
+#define DRVNAME "f71808e_wdt"
+
+#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
+#define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
+#define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
+
+#define SIO_REG_LDSEL		0x07	/* Logical device select */
+#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
+#define SIO_REG_DEVREV		0x22	/* Device revision */
+#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE		0x30	/* Logical device enable */
+#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
+#define SIO_F71858_ID		0x0507  /* Chipset ID */
+#define SIO_F71862_ID		0x0601	/* Chipset ID */
+#define SIO_F71882_ID		0x0541	/* Chipset ID */
+#define SIO_F71889_ID		0x0723	/* Chipset ID */
+
+#define	F71882FG_REG_START		0x01
+
+#define F71808FG_REG_WDO_CONF		0xf0
+#define F71808FG_REG_WDT_CONF		0xf5
+#define F71808FG_REG_WD_TIME		0xf6
+
+#define F71808FG_FLAG_WDOUT_EN		7
+
+#define F71808FG_FLAG_WDTMOUT_STS	5
+#define F71808FG_FLAG_WD_EN		5
+#define F71808FG_FLAG_WD_PULSE		4
+#define F71808FG_FLAG_WD_UNIT		3
+
+/* Default values */
+#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
+#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
+#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
+					   watchdog signal */
+
+static unsigned short force_id;
+module_param(force_id, ushort, 0);
+MODULE_PARM_DESC(force_id, "Override the detected device ID");
+
+static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
+static int timeout = 60;	/* default timeout in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in seconds. 1<= timeout <="
+			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
+			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
+module_param(pulse_width, uint, 0);
+MODULE_PARM_DESC(pulse_width,
+	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
+			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+static unsigned int start_withtimeout;
+module_param(start_withtimeout, uint, 0);
+MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
+	" given initial timeout. Zero (default) disables this feature.");
+
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg };
+
+static const char *f71808e_names[] = {
+	"f71808fg",
+	"f71858fg",
+	"f71862fg",
+	"f71882fg",
+	"f71889fg",
+};
+
+/* Super-I/O Function prototypes */
+static inline int superio_inb(int base, int reg);
+static inline int superio_inw(int base, int reg);
+static inline void superio_outb(int base, int reg, u8 val);
+static inline void superio_set_bit(int base, int reg, int bit);
+static inline void superio_clear_bit(int base, int reg, int bit);
+static inline int superio_enter(int base);
+static inline void superio_select(int base, int ld);
+static inline void superio_exit(int base);
+
+struct watchdog_data {
+	unsigned short	sioaddr;
+	enum chips	type;
+	unsigned long	opened;
+	struct mutex	lock;
+	char		expect_close;
+	struct watchdog_info ident;
+
+	unsigned short	timeout;
+	u8		timer_val;	/* content for the wd_time register */
+	char		minutes_mode;
+	u8		pulse_val;	/* pulse width flag */
+	char		pulse_mode;	/* enable pulse output mode? */
+	char		caused_reboot;	/* last reboot was by the watchdog */
+};
+
+static struct watchdog_data watchdog = {
+	.lock = __MUTEX_INITIALIZER(watchdog.lock),
+};
+
+/* Super I/O functions */
+static inline int superio_inb(int base, int reg)
+{
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static int superio_inw(int base, int reg)
+{
+	int val;
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
+	return val;
+}
+
+static inline void superio_outb(int base, int reg, u8 val)
+{
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static inline void superio_set_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__set_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__clear_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline int superio_enter(int base)
+{
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
+	/* according to the datasheet the key must be send twice! */
+	outb(SIO_UNLOCK_KEY, base);
+	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
+}
+
+static inline void superio_select(int base, int ld)
+{
+	outb(SIO_REG_LDSEL, base);
+	outb(ld, base + 1);
+}
+
+static inline void superio_exit(int base)
+{
+	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
+}
+
+static int watchdog_set_timeout(int timeout)
+{
+	if (timeout <= 0
+	 || timeout >  max_timeout) {
+		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&watchdog.lock);
+
+	watchdog.timeout = timeout;
+	if (timeout > 0xff) {
+		watchdog.timer_val = DIV_ROUND_UP(timeout, 60);
+		watchdog.minutes_mode = true;
+	} else {
+		watchdog.timer_val = timeout;
+		watchdog.minutes_mode = false;
+	}
+
+	mutex_unlock(&watchdog.lock);
+
+	return 0;
+}
+
+static int watchdog_set_pulse_width(unsigned int pw)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+
+	if        (pw <=    1) {
+		watchdog.pulse_val = 0;
+	} else if (pw <=   25) {
+		watchdog.pulse_val = 1;
+	} else if (pw <=  125) {
+		watchdog.pulse_val = 2;
+	} else if (pw <= 5000) {
+		watchdog.pulse_val = 3;
+	} else {
+		printk(KERN_ERR DRVNAME ": pulse width out of range\n");
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+
+	watchdog.pulse_mode = pw;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_keepalive(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	if (watchdog.minutes_mode)
+		/* select minutes for timer units */
+		superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+	else
+		/* select seconds for timer units */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+
+	/* Set timer value */
+	superio_outb(watchdog.sioaddr, F71808FG_REG_WD_TIME,
+			   watchdog.timer_val);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_start(void)
+{
+	/* Make sure we don't die as soon as the watchdog is enabled below */
+	int err = watchdog_keepalive();
+	if (err)
+		return err;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	/* Watchdog pin configuration */
+	switch (watchdog.type) {
+	case f71808fg:
+		/* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */
+		superio_clear_bit(watchdog.sioaddr, 0x2a, 3);
+		superio_clear_bit(watchdog.sioaddr, 0x2b, 3);
+		break;
+
+	case f71882fg:
+		/* Set pin 56 to WDTRST# */
+		superio_set_bit(watchdog.sioaddr, 0x29, 1);
+		break;
+
+	default:
+		/*
+		 * 'default' label to shut up the compiler and catch
+		 * programmer errors
+		 */
+		err = -ENODEV;
+		goto exit_superio;
+	}
+
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+	superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0);
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF,
+			F71808FG_FLAG_WDOUT_EN);
+
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	if (watchdog.pulse_mode) {
+		/* Select "pulse" output mode with given duration */
+		u8 wdt_conf = superio_inb(watchdog.sioaddr,
+				F71808FG_REG_WDT_CONF);
+
+		/* Set WD_PSWIDTH bits (1:0) */
+		wdt_conf = (wdt_conf & 0xfc) | (watchdog.pulse_val & 0x03);
+		/* Set WD_PULSE to "pulse" mode */
+		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
+
+		superio_outb(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				wdt_conf);
+	} else {
+		/* Select "level" output mode */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_PULSE);
+	}
+
+exit_superio:
+	superio_exit(watchdog.sioaddr);
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_stop(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_get_status(void)
+{
+	int status = 0;
+
+	mutex_lock(&watchdog.lock);
+	status = (watchdog.caused_reboot) ? WDIOF_CARDRESET : 0;
+	mutex_unlock(&watchdog.lock);
+
+	return status;
+}
+
+static bool watchdog_is_running(void)
+{
+	/*
+	 * if we fail to determine the watchdog's status assume it to be
+	 * running to be on the safe side
+	 */
+	bool is_running = true;
+
+	mutex_lock(&watchdog.lock);
+	if (superio_enter(watchdog.sioaddr))
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0))
+		&& (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF)
+			& F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return is_running;
+}
+
+/* /dev/watchdog api */
+
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	int err;
+
+	/* If the watchdog is alive we don't need to start it again */
+	if (test_and_set_bit(0, &watchdog.opened))
+		return -EBUSY;
+
+	err = watchdog_start();
+	if (err) {
+		clear_bit(0, &watchdog.opened);
+		return err;
+	}
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	watchdog.expect_close = 0;
+	return nonseekable_open(inode, file);
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &watchdog.opened);
+
+	if (!watchdog.expect_close) {
+		watchdog_keepalive();
+		printk(KERN_CRIT DRVNAME
+			": Unexpected close, not stopping watchdog!\n");
+	} else if (!nowayout) {
+		watchdog_stop();
+	}
+	return 0;
+}
+
+/*
+ *      watchdog_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t watchdog_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			bool expect_close = false;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				expect_close = (c == 'V');
+			}
+
+			/* Properly order writes across fork()ed processes */
+			mutex_lock(&watchdog.lock);
+			watchdog.expect_close = expect_close;
+			mutex_unlock(&watchdog.lock);
+		}
+
+		/* someone wrote to us, we should restart timer */
+		watchdog_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      watchdog_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+static long watchdog_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	int status;
+	int new_options;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &watchdog.ident,
+			sizeof(watchdog.ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		status = watchdog_get_status();
+		if (status < 0)
+			return status;
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD)
+			watchdog_stop();
+
+		if (new_options & WDIOS_ENABLECARD)
+			return watchdog_start();
+
+
+	case WDIOC_KEEPALIVE:
+		watchdog_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (watchdog_set_timeout(new_timeout))
+			return -EINVAL;
+
+		watchdog_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(watchdog.timeout, uarg.i);
+
+	default:
+		return -ENOTTY;
+
+	}
+}
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		watchdog_stop();
+	return NOTIFY_DONE;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= watchdog_open,
+	.release	= watchdog_release,
+	.write		= watchdog_write,
+	.unlocked_ioctl	= watchdog_ioctl,
+};
+
+static struct miscdevice watchdog_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &watchdog_fops,
+};
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+static int __init watchdog_init(int sioaddr)
+{
+	int wdt_conf, err = 0;
+
+	/* No need to lock watchdog.lock here because no entry points
+	 * into the module have been registered yet.
+	 */
+	watchdog.sioaddr = sioaddr;
+	watchdog.ident.options = WDIOC_SETTIMEOUT
+				| WDIOF_MAGICCLOSE
+				| WDIOF_KEEPALIVEPING;
+
+	snprintf(watchdog.ident.identity,
+		sizeof(watchdog.ident.identity), "%s watchdog",
+		f71808e_names[watchdog.type]);
+
+	err = superio_enter(sioaddr);
+	if (err)
+		return err;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF);
+	watchdog.caused_reboot = wdt_conf & F71808FG_FLAG_WDTMOUT_STS;
+
+	superio_exit(sioaddr);
+
+	err = watchdog_set_timeout(timeout);
+	if (err)
+		return err;
+	err = watchdog_set_pulse_width(pulse_width);
+	if (err)
+		return err;
+
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err)
+		return err;
+
+	err = misc_register(&watchdog_miscdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME
+			": cannot register miscdev on minor=%d\n",
+				watchdog_miscdev.minor);
+		goto exit_reboot;
+	}
+
+	if (start_withtimeout) {
+		if (start_withtimeout <= 0
+		 || start_withtimeout >  max_timeout) {
+			printk(KERN_ERR DRVNAME
+				": starting timeout out of range\n");
+			err = -EINVAL;
+			goto exit_miscdev;
+		}
+
+		err = watchdog_start();
+		if (err) {
+			printk(KERN_ERR DRVNAME
+				": cannot start watchdog timer\n");
+			goto exit_miscdev;
+		}
+
+		mutex_lock(&watchdog.lock);
+		err = superio_enter(sioaddr);
+		if (err)
+			goto exit_unlock;
+		superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+		if (start_withtimeout > 0xff) {
+			/* select minutes for timer units */
+			superio_set_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				DIV_ROUND_UP(start_withtimeout, 60));
+		} else {
+			/* select seconds for timer units */
+			superio_clear_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				start_withtimeout);
+		}
+
+		superio_exit(sioaddr);
+		mutex_unlock(&watchdog.lock);
+
+		if (nowayout)
+			__module_get(THIS_MODULE);
+
+		printk(KERN_INFO DRVNAME
+			": watchdog started with initial timeout of %u sec\n",
+			start_withtimeout);
+	}
+
+	return 0;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+exit_miscdev:
+	misc_deregister(&watchdog_miscdev);
+exit_reboot:
+	unregister_reboot_notifier(&watchdog_notifier);
+
+	return err;
+}
+
+static int __init f71808e_find(int sioaddr)
+{
+	u16 devid;
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
+
+	devid = superio_inw(sioaddr, SIO_REG_MANID);
+	if (devid != SIO_FINTEK_ID) {
+		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
+	switch (devid) {
+	case SIO_F71808_ID:
+		watchdog.type = f71808fg;
+		break;
+	case SIO_F71882_ID:
+		watchdog.type = f71882fg;
+		break;
+	case SIO_F71862_ID:
+	case SIO_F71889_ID:
+		/* These have a watchdog, though it isn't implemented (yet). */
+		err = -ENOSYS;
+		goto exit;
+	case SIO_F71858_ID:
+		/* Confirmed (by datasheet) not to have a watchdog. */
+		err = -ENODEV;
+		goto exit;
+	default:
+		printk(KERN_INFO DRVNAME ": Unrecognized Fintek device: %04x\n",
+		       (unsigned int)devid);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	printk(KERN_INFO DRVNAME ": Found %s watchdog chip, revision %d\n",
+		f71808e_names[watchdog.type],
+		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
+exit:
+	superio_exit(sioaddr);
+	return err;
+}
+
+static int __init f71808e_init(void)
+{
+	static const unsigned short addrs[] = { 0x2e, 0x4e };
+	int err = -ENODEV;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
+		err = f71808e_find(addrs[i]);
+		if (err == 0)
+			break;
+	}
+	if (i == ARRAY_SIZE(addrs))
+		return err;
+
+	return watchdog_init(addrs[i]);
+}
+
+static void __exit f71808e_exit(void)
+{
+	if (watchdog_is_running()) {
+		printk(KERN_WARNING DRVNAME
+			": Watchdog timer still running, stopping it\n");
+		watchdog_stop();
+	}
+	misc_deregister(&watchdog_miscdev);
+	unregister_reboot_notifier(&watchdog_notifier);
+}
+
+MODULE_DESCRIPTION("F71808E Watchdog Driver");
+MODULE_AUTHOR("Giel van Schijndel <me@mortis.eu>");
+MODULE_LICENSE("GPL");
+
+module_init(f71808e_init);
+module_exit(f71808e_exit);
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [PATCH 2/2] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E and F71882FG
@ 2010-08-01 13:30                     ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-01 13:30 UTC (permalink / raw)
  Cc: Laurens Leemans, Jonathan Cameron, Giel van Schijndel,
	Wim Van Sebroeck, Andrew Morton, Russell King, Tony Lindgren,
	Marc Zyngier, Thierry Reding, linux-watchdog, linux-kernel

Add a new watchdog driver for the Fintek F71808E and F71882FG Super I/O
controllers.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/watchdog/Kconfig       |   11 +
 drivers/watchdog/Makefile      |    1 +
 drivers/watchdog/f71808e_wdt.c |  768 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 780 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/f71808e_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index afcfacc..edfd57d 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -401,6 +401,17 @@ config ALIM7101_WDT
 
 	  Most people will say N.
 
+config F71808E_WDT
+	tristate "Fintek F71808E and F71882FG Watchdog"
+	depends on X86 && EXPERIMENTAL
+	help
+	  This is the driver for the hardware watchdog on the Fintek
+	  F71808E and F71882FG Super I/O controllers.
+
+	  You can compile this driver directly into the kernel, or use
+	  it as a module.  The module will be called f71808e_wdt.
+
+
 config GEODE_WDT
 	tristate "AMD Geode CS5535/CS5536 Watchdog"
 	depends on CS5535_MFGPT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 72f3e20..9e3d616 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
 obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
 obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
+obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
 obj-$(CONFIG_GEODE_WDT) += geodewdt.o
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
 obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
new file mode 100644
index 0000000..7e5c266
--- /dev/null
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -0,0 +1,768 @@
+/***************************************************************************
+ *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
+ *   Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com>           *
+ *   Copyright (C) 2010 Giel van Schijndel <me@mortis.eu>                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+
+#define DRVNAME "f71808e_wdt"
+
+#define SIO_F71808FG_LD_WDT	0x07	/* Watchdog timer logical device */
+#define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
+#define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
+
+#define SIO_REG_LDSEL		0x07	/* Logical device select */
+#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
+#define SIO_REG_DEVREV		0x22	/* Device revision */
+#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE		0x30	/* Logical device enable */
+#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
+#define SIO_F71808_ID		0x0901  /* Chipset ID */
+#define SIO_F71858_ID		0x0507  /* Chipset ID */
+#define SIO_F71862_ID		0x0601	/* Chipset ID */
+#define SIO_F71882_ID		0x0541	/* Chipset ID */
+#define SIO_F71889_ID		0x0723	/* Chipset ID */
+
+#define	F71882FG_REG_START		0x01
+
+#define F71808FG_REG_WDO_CONF		0xf0
+#define F71808FG_REG_WDT_CONF		0xf5
+#define F71808FG_REG_WD_TIME		0xf6
+
+#define F71808FG_FLAG_WDOUT_EN		7
+
+#define F71808FG_FLAG_WDTMOUT_STS	5
+#define F71808FG_FLAG_WD_EN		5
+#define F71808FG_FLAG_WD_PULSE		4
+#define F71808FG_FLAG_WD_UNIT		3
+
+/* Default values */
+#define WATCHDOG_TIMEOUT	60	/* 1 minute default timeout */
+#define WATCHDOG_MAX_TIMEOUT	(60 * 255)
+#define WATCHDOG_PULSE_WIDTH	125	/* 125 ms, default pulse width for
+					   watchdog signal */
+
+static unsigned short force_id;
+module_param(force_id, ushort, 0);
+MODULE_PARM_DESC(force_id, "Override the detected device ID");
+
+static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
+static int timeout = 60;	/* default timeout in seconds */
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+	"Watchdog timeout in seconds. 1<= timeout <="
+			__MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default="
+			__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+
+static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH;
+module_param(pulse_width, uint, 0);
+MODULE_PARM_DESC(pulse_width,
+	"Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
+			" (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0444);
+MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
+
+static unsigned int start_withtimeout;
+module_param(start_withtimeout, uint, 0);
+MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
+	" given initial timeout. Zero (default) disables this feature.");
+
+enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg };
+
+static const char *f71808e_names[] = {
+	"f71808fg",
+	"f71858fg",
+	"f71862fg",
+	"f71882fg",
+	"f71889fg",
+};
+
+/* Super-I/O Function prototypes */
+static inline int superio_inb(int base, int reg);
+static inline int superio_inw(int base, int reg);
+static inline void superio_outb(int base, int reg, u8 val);
+static inline void superio_set_bit(int base, int reg, int bit);
+static inline void superio_clear_bit(int base, int reg, int bit);
+static inline int superio_enter(int base);
+static inline void superio_select(int base, int ld);
+static inline void superio_exit(int base);
+
+struct watchdog_data {
+	unsigned short	sioaddr;
+	enum chips	type;
+	unsigned long	opened;
+	struct mutex	lock;
+	char		expect_close;
+	struct watchdog_info ident;
+
+	unsigned short	timeout;
+	u8		timer_val;	/* content for the wd_time register */
+	char		minutes_mode;
+	u8		pulse_val;	/* pulse width flag */
+	char		pulse_mode;	/* enable pulse output mode? */
+	char		caused_reboot;	/* last reboot was by the watchdog */
+};
+
+static struct watchdog_data watchdog = {
+	.lock = __MUTEX_INITIALIZER(watchdog.lock),
+};
+
+/* Super I/O functions */
+static inline int superio_inb(int base, int reg)
+{
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static int superio_inw(int base, int reg)
+{
+	int val;
+	val  = superio_inb(base, reg) << 8;
+	val |= superio_inb(base, reg + 1);
+	return val;
+}
+
+static inline void superio_outb(int base, int reg, u8 val)
+{
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static inline void superio_set_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__set_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline void superio_clear_bit(int base, int reg, int bit)
+{
+	unsigned long val = superio_inb(base, reg);
+	__clear_bit(bit, &val);
+	superio_outb(base, reg, val);
+}
+
+static inline int superio_enter(int base)
+{
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				(int)base);
+		return -EBUSY;
+	}
+
+	/* according to the datasheet the key must be send twice! */
+	outb(SIO_UNLOCK_KEY, base);
+	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
+}
+
+static inline void superio_select(int base, int ld)
+{
+	outb(SIO_REG_LDSEL, base);
+	outb(ld, base + 1);
+}
+
+static inline void superio_exit(int base)
+{
+	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
+}
+
+static int watchdog_set_timeout(int timeout)
+{
+	if (timeout <= 0
+	 || timeout >  max_timeout) {
+		printk(KERN_ERR DRVNAME ": watchdog timeout out of range\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&watchdog.lock);
+
+	watchdog.timeout = timeout;
+	if (timeout > 0xff) {
+		watchdog.timer_val = DIV_ROUND_UP(timeout, 60);
+		watchdog.minutes_mode = true;
+	} else {
+		watchdog.timer_val = timeout;
+		watchdog.minutes_mode = false;
+	}
+
+	mutex_unlock(&watchdog.lock);
+
+	return 0;
+}
+
+static int watchdog_set_pulse_width(unsigned int pw)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+
+	if        (pw <=    1) {
+		watchdog.pulse_val = 0;
+	} else if (pw <=   25) {
+		watchdog.pulse_val = 1;
+	} else if (pw <=  125) {
+		watchdog.pulse_val = 2;
+	} else if (pw <= 5000) {
+		watchdog.pulse_val = 3;
+	} else {
+		printk(KERN_ERR DRVNAME ": pulse width out of range\n");
+		err = -EINVAL;
+		goto exit_unlock;
+	}
+
+	watchdog.pulse_mode = pw;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_keepalive(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	if (watchdog.minutes_mode)
+		/* select minutes for timer units */
+		superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+	else
+		/* select seconds for timer units */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+
+	/* Set timer value */
+	superio_outb(watchdog.sioaddr, F71808FG_REG_WD_TIME,
+			   watchdog.timer_val);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return err;
+}
+
+static int watchdog_start(void)
+{
+	/* Make sure we don't die as soon as the watchdog is enabled below */
+	int err = watchdog_keepalive();
+	if (err)
+		return err;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	/* Watchdog pin configuration */
+	switch (watchdog.type) {
+	case f71808fg:
+		/* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */
+		superio_clear_bit(watchdog.sioaddr, 0x2a, 3);
+		superio_clear_bit(watchdog.sioaddr, 0x2b, 3);
+		break;
+
+	case f71882fg:
+		/* Set pin 56 to WDTRST# */
+		superio_set_bit(watchdog.sioaddr, 0x29, 1);
+		break;
+
+	default:
+		/*
+		 * 'default' label to shut up the compiler and catch
+		 * programmer errors
+		 */
+		err = -ENODEV;
+		goto exit_superio;
+	}
+
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+	superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0);
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDO_CONF,
+			F71808FG_FLAG_WDOUT_EN);
+
+	superio_set_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	if (watchdog.pulse_mode) {
+		/* Select "pulse" output mode with given duration */
+		u8 wdt_conf = superio_inb(watchdog.sioaddr,
+				F71808FG_REG_WDT_CONF);
+
+		/* Set WD_PSWIDTH bits (1:0) */
+		wdt_conf = (wdt_conf & 0xfc) | (watchdog.pulse_val & 0x03);
+		/* Set WD_PULSE to "pulse" mode */
+		wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE);
+
+		superio_outb(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				wdt_conf);
+	} else {
+		/* Select "level" output mode */
+		superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_PULSE);
+	}
+
+exit_superio:
+	superio_exit(watchdog.sioaddr);
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_stop(void)
+{
+	int err = 0;
+
+	mutex_lock(&watchdog.lock);
+	err = superio_enter(watchdog.sioaddr);
+	if (err)
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	superio_clear_bit(watchdog.sioaddr, F71808FG_REG_WDT_CONF,
+			F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+
+	return err;
+}
+
+static int watchdog_get_status(void)
+{
+	int status = 0;
+
+	mutex_lock(&watchdog.lock);
+	status = (watchdog.caused_reboot) ? WDIOF_CARDRESET : 0;
+	mutex_unlock(&watchdog.lock);
+
+	return status;
+}
+
+static bool watchdog_is_running(void)
+{
+	/*
+	 * if we fail to determine the watchdog's status assume it to be
+	 * running to be on the safe side
+	 */
+	bool is_running = true;
+
+	mutex_lock(&watchdog.lock);
+	if (superio_enter(watchdog.sioaddr))
+		goto exit_unlock;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0))
+		&& (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF)
+			& F71808FG_FLAG_WD_EN);
+
+	superio_exit(watchdog.sioaddr);
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+	return is_running;
+}
+
+/* /dev/watchdog api */
+
+static int watchdog_open(struct inode *inode, struct file *file)
+{
+	int err;
+
+	/* If the watchdog is alive we don't need to start it again */
+	if (test_and_set_bit(0, &watchdog.opened))
+		return -EBUSY;
+
+	err = watchdog_start();
+	if (err) {
+		clear_bit(0, &watchdog.opened);
+		return err;
+	}
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	watchdog.expect_close = 0;
+	return nonseekable_open(inode, file);
+}
+
+static int watchdog_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &watchdog.opened);
+
+	if (!watchdog.expect_close) {
+		watchdog_keepalive();
+		printk(KERN_CRIT DRVNAME
+			": Unexpected close, not stopping watchdog!\n");
+	} else if (!nowayout) {
+		watchdog_stop();
+	}
+	return 0;
+}
+
+/*
+ *      watchdog_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t watchdog_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			bool expect_close = false;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				expect_close = (c == 'V');
+			}
+
+			/* Properly order writes across fork()ed processes */
+			mutex_lock(&watchdog.lock);
+			watchdog.expect_close = expect_close;
+			mutex_unlock(&watchdog.lock);
+		}
+
+		/* someone wrote to us, we should restart timer */
+		watchdog_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      watchdog_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+static long watchdog_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	int status;
+	int new_options;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &watchdog.ident,
+			sizeof(watchdog.ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		status = watchdog_get_status();
+		if (status < 0)
+			return status;
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD)
+			watchdog_stop();
+
+		if (new_options & WDIOS_ENABLECARD)
+			return watchdog_start();
+
+
+	case WDIOC_KEEPALIVE:
+		watchdog_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (watchdog_set_timeout(new_timeout))
+			return -EINVAL;
+
+		watchdog_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(watchdog.timeout, uarg.i);
+
+	default:
+		return -ENOTTY;
+
+	}
+}
+
+static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT)
+		watchdog_stop();
+	return NOTIFY_DONE;
+}
+
+static const struct file_operations watchdog_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.open		= watchdog_open,
+	.release	= watchdog_release,
+	.write		= watchdog_write,
+	.unlocked_ioctl	= watchdog_ioctl,
+};
+
+static struct miscdevice watchdog_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &watchdog_fops,
+};
+
+static struct notifier_block watchdog_notifier = {
+	.notifier_call = watchdog_notify_sys,
+};
+
+static int __init watchdog_init(int sioaddr)
+{
+	int wdt_conf, err = 0;
+
+	/* No need to lock watchdog.lock here because no entry points
+	 * into the module have been registered yet.
+	 */
+	watchdog.sioaddr = sioaddr;
+	watchdog.ident.options = WDIOC_SETTIMEOUT
+				| WDIOF_MAGICCLOSE
+				| WDIOF_KEEPALIVEPING;
+
+	snprintf(watchdog.ident.identity,
+		sizeof(watchdog.ident.identity), "%s watchdog",
+		f71808e_names[watchdog.type]);
+
+	err = superio_enter(sioaddr);
+	if (err)
+		return err;
+	superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+	wdt_conf = superio_inb(sioaddr, F71808FG_REG_WDT_CONF);
+	watchdog.caused_reboot = wdt_conf & F71808FG_FLAG_WDTMOUT_STS;
+
+	superio_exit(sioaddr);
+
+	err = watchdog_set_timeout(timeout);
+	if (err)
+		return err;
+	err = watchdog_set_pulse_width(pulse_width);
+	if (err)
+		return err;
+
+	err = register_reboot_notifier(&watchdog_notifier);
+	if (err)
+		return err;
+
+	err = misc_register(&watchdog_miscdev);
+	if (err) {
+		printk(KERN_ERR DRVNAME
+			": cannot register miscdev on minor=%d\n",
+				watchdog_miscdev.minor);
+		goto exit_reboot;
+	}
+
+	if (start_withtimeout) {
+		if (start_withtimeout <= 0
+		 || start_withtimeout >  max_timeout) {
+			printk(KERN_ERR DRVNAME
+				": starting timeout out of range\n");
+			err = -EINVAL;
+			goto exit_miscdev;
+		}
+
+		err = watchdog_start();
+		if (err) {
+			printk(KERN_ERR DRVNAME
+				": cannot start watchdog timer\n");
+			goto exit_miscdev;
+		}
+
+		mutex_lock(&watchdog.lock);
+		err = superio_enter(sioaddr);
+		if (err)
+			goto exit_unlock;
+		superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
+
+		if (start_withtimeout > 0xff) {
+			/* select minutes for timer units */
+			superio_set_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				DIV_ROUND_UP(start_withtimeout, 60));
+		} else {
+			/* select seconds for timer units */
+			superio_clear_bit(sioaddr, F71808FG_REG_WDT_CONF,
+				F71808FG_FLAG_WD_UNIT);
+			superio_outb(sioaddr, F71808FG_REG_WD_TIME,
+				start_withtimeout);
+		}
+
+		superio_exit(sioaddr);
+		mutex_unlock(&watchdog.lock);
+
+		if (nowayout)
+			__module_get(THIS_MODULE);
+
+		printk(KERN_INFO DRVNAME
+			": watchdog started with initial timeout of %u sec\n",
+			start_withtimeout);
+	}
+
+	return 0;
+
+exit_unlock:
+	mutex_unlock(&watchdog.lock);
+exit_miscdev:
+	misc_deregister(&watchdog_miscdev);
+exit_reboot:
+	unregister_reboot_notifier(&watchdog_notifier);
+
+	return err;
+}
+
+static int __init f71808e_find(int sioaddr)
+{
+	u16 devid;
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
+
+	devid = superio_inw(sioaddr, SIO_REG_MANID);
+	if (devid != SIO_FINTEK_ID) {
+		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
+	switch (devid) {
+	case SIO_F71808_ID:
+		watchdog.type = f71808fg;
+		break;
+	case SIO_F71882_ID:
+		watchdog.type = f71882fg;
+		break;
+	case SIO_F71862_ID:
+	case SIO_F71889_ID:
+		/* These have a watchdog, though it isn't implemented (yet). */
+		err = -ENOSYS;
+		goto exit;
+	case SIO_F71858_ID:
+		/* Confirmed (by datasheet) not to have a watchdog. */
+		err = -ENODEV;
+		goto exit;
+	default:
+		printk(KERN_INFO DRVNAME ": Unrecognized Fintek device: %04x\n",
+		       (unsigned int)devid);
+		err = -ENODEV;
+		goto exit;
+	}
+
+	printk(KERN_INFO DRVNAME ": Found %s watchdog chip, revision %d\n",
+		f71808e_names[watchdog.type],
+		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
+exit:
+	superio_exit(sioaddr);
+	return err;
+}
+
+static int __init f71808e_init(void)
+{
+	static const unsigned short addrs[] = { 0x2e, 0x4e };
+	int err = -ENODEV;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(addrs); i++) {
+		err = f71808e_find(addrs[i]);
+		if (err == 0)
+			break;
+	}
+	if (i == ARRAY_SIZE(addrs))
+		return err;
+
+	return watchdog_init(addrs[i]);
+}
+
+static void __exit f71808e_exit(void)
+{
+	if (watchdog_is_running()) {
+		printk(KERN_WARNING DRVNAME
+			": Watchdog timer still running, stopping it\n");
+		watchdog_stop();
+	}
+	misc_deregister(&watchdog_miscdev);
+	unregister_reboot_notifier(&watchdog_notifier);
+}
+
+MODULE_DESCRIPTION("F71808E Watchdog Driver");
+MODULE_AUTHOR("Giel van Schijndel <me@mortis.eu>");
+MODULE_LICENSE("GPL");
+
+module_init(f71808e_init);
+module_exit(f71808e_exit);
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-01 13:30                   ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Fintek Giel van Schijndel
  (?)
@ 2010-08-04 11:36                   ` Hans de Goede
  2010-08-04 15:44                     ` Giel van Schijndel
  2010-08-10 19:11                       ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Giel van Schijndel
  -1 siblings, 2 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-04 11:36 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Laurens Leemans, Jonathan Cameron, Randy Dunlap, Jean Delvare,
	Andrew Morton, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

Hi,

I know I've reviewed this patch before, but now I have a datasheet
so this time I've been a bit more thorough and I've found 2 small
issues and 1 bigger one.

Andrew can you please drop this patch from -mm until this is resolved?

On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
> Allow device probing to recognise the Fintek F71808E.
>
> Sysfs interface:
>   * Fan/pwm control is the same as for F71889FG

My datasheet strongly disagrees with this the F71889FG has 5 pwm zones
each with their own speed divided by 4 boundary temps, where as
the F71808E has 3 pwm zones divided by 2 boundary temps. So it is much
more like the F71862FG, which also has 2 boundary temps, and 3 pwm zones,
*but* the F71862FG has one pwm zone hardwired to 100%.

So it looks like you need to create a new f71808e_auto_pwm_attr array
esp. for this model, as well as a special case for reading the
auto pwm attr in f71882fg_update_device.

Also the auto pwm of the F71808E allows following of digital temps
read to peci / amdsi / ibex rather then following a directly connected
temp diode like the F71889FG, which the driver does not support, so
you should check if this is enabled and if so disable the auto pwm
attr entirely. Code for this is already in place for the F71889FG,
you simply need to make it trigger when the chip is a F71808E too.

>   * Temperature and voltage sensor handling is largely the same as for
>     the F71889FG
>    - Has one temperature sensor less (doesn't have temp3)
>    - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>      what in7_input refers for F71889FG)
>
> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
> such that it can largely be reused.

There is a problem here though, the new fxxxx_temp_attr contains
attributes for temp#_max_beep and temp#_crit_beep, but the F71808E
lacks that function. So I think that the new fxxxx_temp_attr
need to be split into fxxxx_temp_attr and fxxxx_temp_beep_attr,
like is already done with fxxxx_fan_attr.

Also while making changes, I must say I don't like the splitting
of fxxxx_temp_attr into fxxxx_temp_attr and f71862_temp_attr just because
the number of sensors differs. I think it would be better to instead
make fxxxx_temp_attr a 2 dimensional array like fxxxx_fan_attr and like
with fxxxx_fan_attr register as many sensor attr blocks as the specific
model has.

> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   Documentation/hwmon/f71882fg |    4 ++
>   drivers/hwmon/Kconfig        |    6 ++--
>   drivers/hwmon/f71882fg.c     |   83 ++++++++++++++++++++++++++++++++++++++----
>   3 files changed, 82 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
> index a7952c2..1a07fd6 100644
> --- a/Documentation/hwmon/f71882fg
> +++ b/Documentation/hwmon/f71882fg
> @@ -2,6 +2,10 @@ Kernel driver f71882fg
>   ======================
>
>   Supported chips:
> +  * Fintek F71808E
> +    Prefix: 'f71808fg'

This is wrong, as you already indicate and the datasheet as well this
chip in question is an f71808e not an f71808fg, also note that there is
an f71808a model as well which is different (and has a different super io
chip id).

One last request in the second switch case in f71882fg_remove()
there is a default label which contains a comment which models it applies
to, please add the f71808e to that comment.

Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-08-01 13:30                   ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock Giel van Schijndel
  (?)
  (?)
@ 2010-08-04 11:38                   ` Hans de Goede
  2010-10-02 22:59                       ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource Giel van Schijndel
  -1 siblings, 1 reply; 159+ messages in thread
From: Hans de Goede @ 2010-08-04 11:38 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Laurens Leemans, Jonathan Cameron, Jean Delvare, lm-sensors,
	linux-kernel

Ack!

Acked-by: Hans de Goede <hdegoede@redhat.com>

On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
> Sleep while acquiring a resource lock on the Super I/O port. This should
> prevent collisions from causing the hardware probe to fail with -EBUSY.
>
> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> ---
>   drivers/hwmon/f71882fg.c |   32 +++++++++++++++++++-------------
>   1 files changed, 19 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 7857ed3..267cb92 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -113,7 +113,7 @@ static struct platform_device *f71882fg_pdev;
>   /* Super-I/O Function prototypes */
>   static inline int superio_inb(int base, int reg);
>   static inline int superio_inw(int base, int reg);
> -static inline void superio_enter(int base);
> +static inline int superio_enter(int base);
>   static inline void superio_select(int base, int ld);
>   static inline void superio_exit(int base);
>
> @@ -883,11 +883,20 @@ static int superio_inw(int base, int reg)
>   	return val;
>   }
>
> -static inline void superio_enter(int base)
> +static inline int superio_enter(int base)
>   {
> +	/* Don't step on other drivers' I/O space by accident */
> +	if (!request_muxed_region(base, 2, DRVNAME)) {
> +		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> +				base);
> +		return -EBUSY;
> +	}
> +
>   	/* according to the datasheet the key must be send twice! */
>   	outb(SIO_UNLOCK_KEY, base);
>   	outb(SIO_UNLOCK_KEY, base);
> +
> +	return 0;
>   }
>
>   static inline void superio_select(int base, int ld)
> @@ -899,6 +908,7 @@ static inline void superio_select(int base, int ld)
>   static inline void superio_exit(int base)
>   {
>   	outb(SIO_LOCK_KEY, base);
> +	release_region(base, 2);
>   }
>
>   static inline int fan_from_reg(u16 reg)
> @@ -2239,21 +2249,15 @@ static int f71882fg_remove(struct platform_device *pdev)
>   static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   	struct f71882fg_sio_data *sio_data)
>   {
> -	int err = -ENODEV;
>   	u16 devid;
> -
> -	/* Don't step on other drivers' I/O space by accident */
> -	if (!request_region(sioaddr, 2, DRVNAME)) {
> -		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
> -				(int)sioaddr);
> -		return -EBUSY;
> -	}
> -
> -	superio_enter(sioaddr);
> +	int err = superio_enter(sioaddr);
> +	if (err)
> +		return err;
>
>   	devid = superio_inw(sioaddr, SIO_REG_MANID);
>   	if (devid != SIO_FINTEK_ID) {
>   		pr_debug(DRVNAME ": Not a Fintek device\n");
> +		err = -ENODEV;
>   		goto exit;
>   	}
>
> @@ -2280,6 +2284,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   	default:
>   		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
>   		       (unsigned int)devid);
> +		err = -ENODEV;
>   		goto exit;
>   	}
>
> @@ -2290,12 +2295,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>
>   	if (!(superio_inb(sioaddr, SIO_REG_ENABLE)&  0x01)) {
>   		printk(KERN_WARNING DRVNAME ": Device not activated\n");
> +		err = -ENODEV;
>   		goto exit;
>   	}
>
>   	*address = superio_inw(sioaddr, SIO_REG_ADDR);
>   	if (*address == 0) {
>   		printk(KERN_WARNING DRVNAME ": Base address not set\n");
> +		err = -ENODEV;
>   		goto exit;
>   	}
>   	*address&= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
> @@ -2306,7 +2313,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
>   		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
>   exit:
>   	superio_exit(sioaddr);
> -	release_region(sioaddr, 2);
>   	return err;
>   }
>

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-04 11:36                   ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Hans de Goede
@ 2010-08-04 15:44                     ` Giel van Schijndel
  2010-08-13 10:56                         ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Hans de Goede
  2010-08-10 19:11                       ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Giel van Schijndel
  1 sibling, 1 reply; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-04 15:44 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Laurens Leemans, Jonathan Cameron, Randy Dunlap, Jean Delvare,
	Andrew Morton, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

[-- Attachment #1: Type: text/plain, Size: 7931 bytes --]

On Wed, Aug 04, 2010 at 13:36:22 +0200, Hans de Goede wrote:
> On 08/01/2010 03:30, Giel van Schijndel wrote:
>> Allow device probing to recognise the Fintek F71808E.
>> 
>> Sysfs interface:
>>   * Fan/pwm control is the same as for F71889FG
> 
> My datasheet strongly disagrees with this the F71889FG has 5 pwm zones
> each with their own speed divided by 4 boundary temps, where as
> the F71808E has 3 pwm zones divided by 2 boundary temps. So it is much
> more like the F71862FG, which also has 2 boundary temps, and 3 pwm zones,
> *but* the F71862FG has one pwm zone hardwired to 100%.

I'm assuming that by "pwm zone" you mean a separate PWM output channel?
I.e. each "pwm zone" controls a single fan?

Because in the datasheet I have for the F71889 only 3 fan controls are
mentioned, not 5, it does however have 4 boundary temps:
> 7.5. Hardware Monitor
> ... snip ...
> ... page 46-47:
> Device registers, the following is a register map order which shows a
> summary of all registers.  Please refer each one register if you want
> more detail information.
> Register CR01 ~ CR03 -> Configuration Registers
> Register CR0A ~ CR0F -> PECI/SST/TSI Control Register
> Register CR10 ~ CR4F -> Voltage Setting Register
> Register CR60 ~ CR8E -> Temperature Setting Register
> Register CR90 ~ CRDF -> Fan Control Setting Register
>                      -> Fan1 Detail Setting CRA0 ~ CRAF
>                      -> Fan2 Detail Setting CRB0 ~ CRBF
>                      -> Fan3 Detail Setting CRC0 ~ CRCF
> Register CR5A ~ CR5D -> HW Chip ID and Vender ID Register

> So it looks like you need to create a new f71808e_auto_pwm_attr array
> esp. for this model, as well as a special case for reading the
> auto pwm attr in f71882fg_update_device.

Ack.

> Also the auto pwm of the F71808E allows following of digital temps
> read to peci / amdsi / ibex rather then following a directly connected
> temp diode like the F71889FG, which the driver does not support, so
> you should check if this is enabled and if so disable the auto pwm
> attr entirely. Code for this is already in place for the F71889FG,
> you simply need to make it trigger when the chip is a F71808E too.

Do you mean the checking of the FANx_TEMP_SEL_DIG flag in the fan's
"Temperature Mapping Select" registers currently done for the F71889 in
the second switch-statement inside f71882fg_probe?  As that code is
already used for the F71808E as well.

>>   * Temperature and voltage sensor handling is largely the same as for
>>     the F71889FG
>>    - Has one temperature sensor less (doesn't have temp3)
>>    - Misses one voltage sensor (doesn't have V6, thus in6_input refers to
>>      what in7_input refers for F71889FG)
>> 
>> For the purpose of the sysfs interface fxxxx_in_temp_attr[] is split up
>> such that it can largely be reused.
> 
> There is a problem here though, the new fxxxx_temp_attr contains
> attributes for temp#_max_beep and temp#_crit_beep, but the F71808E
> lacks that function. So I think that the new fxxxx_temp_attr
> need to be split into fxxxx_temp_attr and fxxxx_temp_beep_attr,
> like is already done with fxxxx_fan_attr.

Ack.

> Also while making changes, I must say I don't like the splitting
> of fxxxx_temp_attr into fxxxx_temp_attr and f71862_temp_attr just because
> the number of sensors differs. I think it would be better to instead
> make fxxxx_temp_attr a 2 dimensional array like fxxxx_fan_attr and like
> with fxxxx_fan_attr register as many sensor attr blocks as the specific
> model has.

Right, that's probably a nicer way of going about it, I think that might
be easier done in a separate patch (most likely preceding the addition
of F71808E support), though I'll look at that.

>> Signed-off-by: Giel van Schijndel<me@mortis.eu>
>> ---
>>   Documentation/hwmon/f71882fg |    4 ++
>>   drivers/hwmon/Kconfig        |    6 ++--
>>   drivers/hwmon/f71882fg.c     |   83 ++++++++++++++++++++++++++++++++++++++----
>>   3 files changed, 82 insertions(+), 11 deletions(-)
>> 
>> diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
>> index a7952c2..1a07fd6 100644
>> --- a/Documentation/hwmon/f71882fg
>> +++ b/Documentation/hwmon/f71882fg
>> @@ -2,6 +2,10 @@ Kernel driver f71882fg
>>   ======================
>> 
>>   Supported chips:
>> +  * Fintek F71808E
>> +    Prefix: 'f71808fg'
> 
> This is wrong, as you already indicate and the datasheet as well this
> chip in question is an f71808e not an f71808fg, also note that there is
> an f71808a model as well which is different (and has a different super io
> chip id).

Ah yes, I think I, wrongly, assumed that 'fg' was just some suffix used
in this driver.  For example, I cannot find F71889FG in the datasheet I
have, only 'F71889' along with 'F71889F' in the section "Ordering
Information" (for the F71889 I've got datasheet version V0.17P released
December 2008).

At the same time the F71808E datasheet I have clearly marks the chip as
F71808E all over the entire datasheet (version V0.17P released October
2009).

Either way I changed that ^^ portion of documentation while changing the
enumeration value 'f71808fg' -> 'f71808e' in the code itself as well.

> One last request in the second switch case in f71882fg_remove()
> there is a default label which contains a comment which models it applies
> to, please add the f71808e to that comment.

Wouldn't it be better, to instead replace that 'default' label with a
serie of case labels that code applies to?  Along with providing the
same documentation effect (expressed in C instead of English) it would
cause GCC to warn whenever one of the chips was forgotten in a switch
statement.  E.g. something similar to this patch:
========================================================================
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index b891b65..bfb2b4c 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -2113,7 +2113,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
                                break;
                        }
                        /* fall through */
-               default: /* f71858fg / f71882fg */
+               case f71858fg:
+               case f71882fg:
                        err = f71882fg_create_sysfs_files(pdev,
                                &fxxxx_auto_pwm_attr[0][0],
                                ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
@@ -2224,7 +2225,10 @@ static int f71882fg_remove(struct platform_device *pdev)
                                        f8000_auto_pwm_attr,
                                        ARRAY_SIZE(f8000_auto_pwm_attr));
                        break;
-               default: /* f71808e / f71858fg / f71882fg / f71889fg */
+               case f71808e:
+               case f71858fg:
+               case f71882fg:
+               case f71889fg:
                        f71882fg_remove_sysfs_files(pdev,
                                &fxxxx_auto_pwm_attr[0][0],
                                ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
========================================================================

PS For comparison, which datasheet versions do you have?
All Fintek datasheets I have access to:
 * F71808E - V0.17P, October 2009
 * F71858  - V0.26P, July 2007
 * F71862  - V0.28P, July 2008
 * F71882  - V0.24P, November 2006
 * F71889  - V0.17P, December 2008

Those most interesting are of course the F71808E, F71862 and F71889---as
you refer to those in your text.  This because I have already had
experience with a hardware vendor giving me the wrong datasheets and
would like to prevent any such mistakes from causing similar
communication problems here.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-04 11:36                   ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Hans de Goede
@ 2010-08-10 19:11                       ` Giel van Schijndel
  2010-08-10 19:11                       ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Giel van Schijndel
  1 sibling, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-10 19:11 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Laurens Leemans, Jonathan Cameron, Randy Dunlap, Jean Delvare,
	Andrew Morton, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

[-- Attachment #1: Type: text/plain, Size: 1393 bytes --]

On Wed, Aug 04, 2010 at 01:36:22PM +0200, Hans de Goede wrote:
> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
>> Allow device probing to recognise the Fintek F71808E.
>> 
>> Sysfs interface:
>>   * Fan/pwm control is the same as for F71889FG
> 
> My datasheet strongly disagrees with this ...

I just noticed this patch was applied to mainline anyway.  Regardless, I
will (try to) address these issues you raised.

Right now however, I am prioritising personal stuff above this
driver---bachelor's thesis and graduation presentation.  When finished
with that (september) I'll allocate time to these issues again.

PS Those datasheets are written very poorly, although I have seen worse.
   And as a reader I tend to become more "lazy" when I discover the
   writer was "lazy" (not exactly by choice, more out of habit).
   Unfortunately that doesn't work very well as reading style with
   technical documentation, so this probably explains some of the errors
   in this current patch.

PPS I do have a patch ready that addresses some of the issues you
    raised.  Those are only the cosmetic changes though (e.g. change
    naming of chip, comment updates, etc.).  Would you suggest me to
    send it right now already or wait until I have time to address the
    other issues as well?

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the
@ 2010-08-10 19:11                       ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-10 19:11 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Laurens Leemans, Jonathan Cameron, Randy Dunlap, Jean Delvare,
	Andrew Morton, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc


[-- Attachment #1.1: Type: text/plain, Size: 1393 bytes --]

On Wed, Aug 04, 2010 at 01:36:22PM +0200, Hans de Goede wrote:
> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
>> Allow device probing to recognise the Fintek F71808E.
>> 
>> Sysfs interface:
>>   * Fan/pwm control is the same as for F71889FG
> 
> My datasheet strongly disagrees with this ...

I just noticed this patch was applied to mainline anyway.  Regardless, I
will (try to) address these issues you raised.

Right now however, I am prioritising personal stuff above this
driver---bachelor's thesis and graduation presentation.  When finished
with that (september) I'll allocate time to these issues again.

PS Those datasheets are written very poorly, although I have seen worse.
   And as a reader I tend to become more "lazy" when I discover the
   writer was "lazy" (not exactly by choice, more out of habit).
   Unfortunately that doesn't work very well as reading style with
   technical documentation, so this probably explains some of the errors
   in this current patch.

PPS I do have a patch ready that addresses some of the issues you
    raised.  Those are only the cosmetic changes though (e.g. change
    naming of chip, comment updates, etc.).  Would you suggest me to
    send it right now already or wait until I have time to address the
    other issues as well?

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-10 19:11                       ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Giel van Schijndel
@ 2010-08-13 10:01                         ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-13 10:01 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Laurens Leemans, Jonathan Cameron, Randy Dunlap, Jean Delvare,
	Andrew Morton, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

Hi,

On 08/10/2010 09:11 PM, Giel van Schijndel wrote:
> On Wed, Aug 04, 2010 at 01:36:22PM +0200, Hans de Goede wrote:
>> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
>>> Allow device probing to recognise the Fintek F71808E.
>>>
>>> Sysfs interface:
>>>    * Fan/pwm control is the same as for F71889FG
>>
>> My datasheet strongly disagrees with this ...
>
> I just noticed this patch was applied to mainline anyway.  Regardless, I
> will (try to) address these issues you raised.
>
> Right now however, I am prioritising personal stuff above this
> driver---bachelor's thesis and graduation presentation.  When finished
> with that (september) I'll allocate time to these issues again.
>

I've send a mail directly to akpm asking for this to be removed, hopefully
this will help.

> PPS I do have a patch ready that addresses some of the issues you
>      raised.  Those are only the cosmetic changes though (e.g. change
>      naming of chip, comment updates, etc.).  Would you suggest me to
>      send it right now already or wait until I have time to address the
>      other issues as well?

My goal for 2.6.36 is to pull the patch, and then we can wait til all
issues are fixed properly before re-introducing it.

Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the
@ 2010-08-13 10:01                         ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-13 10:01 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Laurens Leemans, Jonathan Cameron, Randy Dunlap, Jean Delvare,
	Andrew Morton, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

Hi,

On 08/10/2010 09:11 PM, Giel van Schijndel wrote:
> On Wed, Aug 04, 2010 at 01:36:22PM +0200, Hans de Goede wrote:
>> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
>>> Allow device probing to recognise the Fintek F71808E.
>>>
>>> Sysfs interface:
>>>    * Fan/pwm control is the same as for F71889FG
>>
>> My datasheet strongly disagrees with this ...
>
> I just noticed this patch was applied to mainline anyway.  Regardless, I
> will (try to) address these issues you raised.
>
> Right now however, I am prioritising personal stuff above this
> driver---bachelor's thesis and graduation presentation.  When finished
> with that (september) I'll allocate time to these issues again.
>

I've send a mail directly to akpm asking for this to be removed, hopefully
this will help.

> PPS I do have a patch ready that addresses some of the issues you
>      raised.  Those are only the cosmetic changes though (e.g. change
>      naming of chip, comment updates, etc.).  Would you suggest me to
>      send it right now already or wait until I have time to address the
>      other issues as well?

My goal for 2.6.36 is to pull the patch, and then we can wait til all
issues are fixed properly before re-introducing it.

Regards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-04 15:44                     ` Giel van Schijndel
@ 2010-08-13 10:56                         ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-13 10:56 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Laurens Leemans, Jonathan Cameron, Randy Dunlap, Jean Delvare,
	Andrew Morton, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

Hi,

On 08/04/2010 05:44 PM, Giel van Schijndel wrote:
> On Wed, Aug 04, 2010 at 13:36:22 +0200, Hans de Goede wrote:
>> On 08/01/2010 03:30, Giel van Schijndel wrote:
>>> Allow device probing to recognise the Fintek F71808E.
>>>
>>> Sysfs interface:
>>>    * Fan/pwm control is the same as for F71889FG
>>
>> My datasheet strongly disagrees with this the F71889FG has 5 pwm zones
>> each with their own speed divided by 4 boundary temps, where as
>> the F71808E has 3 pwm zones divided by 2 boundary temps. So it is much
>> more like the F71862FG, which also has 2 boundary temps, and 3 pwm zones,
>> *but* the F71862FG has one pwm zone hardwired to 100%.
>
> I'm assuming that by "pwm zone" you mean a separate PWM output channel?
> I.e. each "pwm zone" controls a single fan?
>

With pwm zone I mean the number of different speeds which can be programmed
for one output channel, the temps divide the entire temp range into zones
(number of zones == number of temps + 1) and for each zone one can then
tell at what speed / pwm setting the fan should operate when the temperature
is in that zone.


<snip>

>> Also while making changes, I must say I don't like the splitting
>> of fxxxx_temp_attr into fxxxx_temp_attr and f71862_temp_attr just because
>> the number of sensors differs. I think it would be better to instead
>> make fxxxx_temp_attr a 2 dimensional array like fxxxx_fan_attr and like
>> with fxxxx_fan_attr register as many sensor attr blocks as the specific
>> model has.
>
> Right, that's probably a nicer way of going about it, I think that might
> be easier done in a separate patch (most likely preceding the addition
> of F71808E support), though I'll look at that.
>

Yes first splitting the attr in a separate patch would be very good.

>>> Signed-off-by: Giel van Schijndel<me@mortis.eu>
>>> ---
>>>    Documentation/hwmon/f71882fg |    4 ++
>>>    drivers/hwmon/Kconfig        |    6 ++--
>>>    drivers/hwmon/f71882fg.c     |   83 ++++++++++++++++++++++++++++++++++++++----
>>>    3 files changed, 82 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
>>> index a7952c2..1a07fd6 100644
>>> --- a/Documentation/hwmon/f71882fg
>>> +++ b/Documentation/hwmon/f71882fg
>>> @@ -2,6 +2,10 @@ Kernel driver f71882fg
>>>    ======================
>>>
>>>    Supported chips:
>>> +  * Fintek F71808E
>>> +    Prefix: 'f71808fg'
>>
>> This is wrong, as you already indicate and the datasheet as well this
>> chip in question is an f71808e not an f71808fg, also note that there is
>> an f71808a model as well which is different (and has a different super io
>> chip id).
>
> Ah yes, I think I, wrongly, assumed that 'fg' was just some suffix used
> in this driver.  For example, I cannot find F71889FG in the datasheet I
> have, only 'F71889' along with 'F71889F' in the section "Ordering
> Information" (for the F71889 I've got datasheet version V0.17P released
> December 2008).
>

I have a V0.27P datasheet for the 71889, but yes the fg suffix does not
seem to be mentioned anywhere in the datasheet not sure where it comes from.
I do know however that there are now new chips coming out with different
a and e suffixes so I suggest that we stay with fg for the old chips and
use a and e to distuingish the new ones.

> At the same time the F71808E datasheet I have clearly marks the chip as
> F71808E all over the entire datasheet (version V0.17P released October
> 2009).
>

Right.

> Either way I changed that ^^ portion of documentation while changing the
> enumeration value 'f71808fg' ->  'f71808e' in the code itself as well.
>

Good.

>> One last request in the second switch case in f71882fg_remove()
>> there is a default label which contains a comment which models it applies
>> to, please add the f71808e to that comment.
>
> Wouldn't it be better, to instead replace that 'default' label with a
> serie of case labels that code applies to?  Along with providing the
> same documentation effect (expressed in C instead of English) it would
> cause GCC to warn whenever one of the chips was forgotten in a switch
> statement.

Ack, if you could do that that would be great! Please do that
in a preparation patch though and not in the main patch.

<snip>

> PS For comparison, which datasheet versions do you have?
> All Fintek datasheets I have access to:
>   * F71808E - V0.17P, October 2009
>   * F71858  - V0.26P, July 2007
>   * F71862  - V0.28P, July 2008
>   * F71882  - V0.24P, November 2006
>   * F71889  - V0.17P, December 2008
>
> Those most interesting are of course the F71808E, F71862 and F71889---as
> you refer to those in your text.  This because I have already had
> experience with a hardware vendor giving me the wrong datasheets and
> would like to prevent any such mistakes from causing similar
> communication problems here.

Here is my list:
F71612A_V020P.pdf
F71808A_V0.15P.pdf
F71808E_V0.20P.pdf
F71858_V026P.pdf
F71862_V028P.pdf
F71869E_V0.19P.pdf
F71869_V1.1.pdf
F71882_V0.24P.pdf
F71889E_V0.19P.pdf
F71889_V0.27P.pdf
F8000_REG.pdf

Regards,

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the
@ 2010-08-13 10:56                         ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-13 10:56 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Laurens Leemans, Jonathan Cameron, Randy Dunlap, Jean Delvare,
	Andrew Morton, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

Hi,

On 08/04/2010 05:44 PM, Giel van Schijndel wrote:
> On Wed, Aug 04, 2010 at 13:36:22 +0200, Hans de Goede wrote:
>> On 08/01/2010 03:30, Giel van Schijndel wrote:
>>> Allow device probing to recognise the Fintek F71808E.
>>>
>>> Sysfs interface:
>>>    * Fan/pwm control is the same as for F71889FG
>>
>> My datasheet strongly disagrees with this the F71889FG has 5 pwm zones
>> each with their own speed divided by 4 boundary temps, where as
>> the F71808E has 3 pwm zones divided by 2 boundary temps. So it is much
>> more like the F71862FG, which also has 2 boundary temps, and 3 pwm zones,
>> *but* the F71862FG has one pwm zone hardwired to 100%.
>
> I'm assuming that by "pwm zone" you mean a separate PWM output channel?
> I.e. each "pwm zone" controls a single fan?
>

With pwm zone I mean the number of different speeds which can be programmed
for one output channel, the temps divide the entire temp range into zones
(number of zones = number of temps + 1) and for each zone one can then
tell at what speed / pwm setting the fan should operate when the temperature
is in that zone.


<snip>

>> Also while making changes, I must say I don't like the splitting
>> of fxxxx_temp_attr into fxxxx_temp_attr and f71862_temp_attr just because
>> the number of sensors differs. I think it would be better to instead
>> make fxxxx_temp_attr a 2 dimensional array like fxxxx_fan_attr and like
>> with fxxxx_fan_attr register as many sensor attr blocks as the specific
>> model has.
>
> Right, that's probably a nicer way of going about it, I think that might
> be easier done in a separate patch (most likely preceding the addition
> of F71808E support), though I'll look at that.
>

Yes first splitting the attr in a separate patch would be very good.

>>> Signed-off-by: Giel van Schijndel<me@mortis.eu>
>>> ---
>>>    Documentation/hwmon/f71882fg |    4 ++
>>>    drivers/hwmon/Kconfig        |    6 ++--
>>>    drivers/hwmon/f71882fg.c     |   83 ++++++++++++++++++++++++++++++++++++++----
>>>    3 files changed, 82 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/Documentation/hwmon/f71882fg b/Documentation/hwmon/f71882fg
>>> index a7952c2..1a07fd6 100644
>>> --- a/Documentation/hwmon/f71882fg
>>> +++ b/Documentation/hwmon/f71882fg
>>> @@ -2,6 +2,10 @@ Kernel driver f71882fg
>>>    ===========
>>>
>>>    Supported chips:
>>> +  * Fintek F71808E
>>> +    Prefix: 'f71808fg'
>>
>> This is wrong, as you already indicate and the datasheet as well this
>> chip in question is an f71808e not an f71808fg, also note that there is
>> an f71808a model as well which is different (and has a different super io
>> chip id).
>
> Ah yes, I think I, wrongly, assumed that 'fg' was just some suffix used
> in this driver.  For example, I cannot find F71889FG in the datasheet I
> have, only 'F71889' along with 'F71889F' in the section "Ordering
> Information" (for the F71889 I've got datasheet version V0.17P released
> December 2008).
>

I have a V0.27P datasheet for the 71889, but yes the fg suffix does not
seem to be mentioned anywhere in the datasheet not sure where it comes from.
I do know however that there are now new chips coming out with different
a and e suffixes so I suggest that we stay with fg for the old chips and
use a and e to distuingish the new ones.

> At the same time the F71808E datasheet I have clearly marks the chip as
> F71808E all over the entire datasheet (version V0.17P released October
> 2009).
>

Right.

> Either way I changed that ^^ portion of documentation while changing the
> enumeration value 'f71808fg' ->  'f71808e' in the code itself as well.
>

Good.

>> One last request in the second switch case in f71882fg_remove()
>> there is a default label which contains a comment which models it applies
>> to, please add the f71808e to that comment.
>
> Wouldn't it be better, to instead replace that 'default' label with a
> serie of case labels that code applies to?  Along with providing the
> same documentation effect (expressed in C instead of English) it would
> cause GCC to warn whenever one of the chips was forgotten in a switch
> statement.

Ack, if you could do that that would be great! Please do that
in a preparation patch though and not in the main patch.

<snip>

> PS For comparison, which datasheet versions do you have?
> All Fintek datasheets I have access to:
>   * F71808E - V0.17P, October 2009
>   * F71858  - V0.26P, July 2007
>   * F71862  - V0.28P, July 2008
>   * F71882  - V0.24P, November 2006
>   * F71889  - V0.17P, December 2008
>
> Those most interesting are of course the F71808E, F71862 and F71889---as
> you refer to those in your text.  This because I have already had
> experience with a hardware vendor giving me the wrong datasheets and
> would like to prevent any such mistakes from causing similar
> communication problems here.

Here is my list:
F71612A_V020P.pdf
F71808A_V0.15P.pdf
F71808E_V0.20P.pdf
F71858_V026P.pdf
F71862_V028P.pdf
F71869E_V0.19P.pdf
F71869_V1.1.pdf
F71882_V0.24P.pdf
F71889E_V0.19P.pdf
F71889_V0.27P.pdf
F8000_REG.pdf

Regards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-13 10:01                         ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Hans de Goede
@ 2010-08-18 18:24                           ` Andrew Morton
  -1 siblings, 0 replies; 159+ messages in thread
From: Andrew Morton @ 2010-08-18 18:24 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Giel van Schijndel, Laurens Leemans, Jonathan Cameron,
	Randy Dunlap, Jean Delvare, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

On Fri, 13 Aug 2010 12:01:36 +0200
Hans de Goede <hdegoede@redhat.com> wrote:

> Hi,
> 
> On 08/10/2010 09:11 PM, Giel van Schijndel wrote:
> > On Wed, Aug 04, 2010 at 01:36:22PM +0200, Hans de Goede wrote:
> >> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
> >>> Allow device probing to recognise the Fintek F71808E.
> >>>
> >>> Sysfs interface:
> >>>    * Fan/pwm control is the same as for F71889FG
> >>
> >> My datasheet strongly disagrees with this ...
> >
> > I just noticed this patch was applied to mainline anyway.  Regardless, I
> > will (try to) address these issues you raised.
> >
> > Right now however, I am prioritising personal stuff above this
> > driver---bachelor's thesis and graduation presentation.  When finished
> > with that (september) I'll allocate time to these issues again.
> >
> 
> I've send a mail directly to akpm asking for this to be removed, hopefully
> this will help.

It seems that I managed to muck up my paperwork and the patch was
merged into mainline.

We can revert it, or we can fix it up in place in time for 2.6.36. 
What do you guys suggest?


^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the
@ 2010-08-18 18:24                           ` Andrew Morton
  0 siblings, 0 replies; 159+ messages in thread
From: Andrew Morton @ 2010-08-18 18:24 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Giel van Schijndel, Laurens Leemans, Jonathan Cameron,
	Randy Dunlap, Jean Delvare, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

On Fri, 13 Aug 2010 12:01:36 +0200
Hans de Goede <hdegoede@redhat.com> wrote:

> Hi,
> 
> On 08/10/2010 09:11 PM, Giel van Schijndel wrote:
> > On Wed, Aug 04, 2010 at 01:36:22PM +0200, Hans de Goede wrote:
> >> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
> >>> Allow device probing to recognise the Fintek F71808E.
> >>>
> >>> Sysfs interface:
> >>>    * Fan/pwm control is the same as for F71889FG
> >>
> >> My datasheet strongly disagrees with this ...
> >
> > I just noticed this patch was applied to mainline anyway.  Regardless, I
> > will (try to) address these issues you raised.
> >
> > Right now however, I am prioritising personal stuff above this
> > driver---bachelor's thesis and graduation presentation.  When finished
> > with that (september) I'll allocate time to these issues again.
> >
> 
> I've send a mail directly to akpm asking for this to be removed, hopefully
> this will help.

It seems that I managed to muck up my paperwork and the patch was
merged into mainline.

We can revert it, or we can fix it up in place in time for 2.6.36. 
What do you guys suggest?


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-18 18:24                           ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Andrew Morton
@ 2010-08-22 18:04                             ` Hans de Goede
  -1 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-22 18:04 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Giel van Schijndel, Laurens Leemans, Jonathan Cameron,
	Randy Dunlap, Jean Delvare, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

Hi,

On 08/18/2010 08:24 PM, Andrew Morton wrote:
> On Fri, 13 Aug 2010 12:01:36 +0200
> Hans de Goede<hdegoede@redhat.com>  wrote:
>
>> Hi,
>>
>> On 08/10/2010 09:11 PM, Giel van Schijndel wrote:
>>> On Wed, Aug 04, 2010 at 01:36:22PM +0200, Hans de Goede wrote:
>>>> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
>>>>> Allow device probing to recognise the Fintek F71808E.
>>>>>
>>>>> Sysfs interface:
>>>>>     * Fan/pwm control is the same as for F71889FG
>>>>
>>>> My datasheet strongly disagrees with this ...
>>>
>>> I just noticed this patch was applied to mainline anyway.  Regardless, I
>>> will (try to) address these issues you raised.
>>>
>>> Right now however, I am prioritising personal stuff above this
>>> driver---bachelor's thesis and graduation presentation.  When finished
>>> with that (september) I'll allocate time to these issues again.
>>>
>>
>> I've send a mail directly to akpm asking for this to be removed, hopefully
>> this will help.
>
> It seems that I managed to muck up my paperwork and the patch was
> merged into mainline.
>
> We can revert it, or we can fix it up in place in time for 2.6.36.
> What do you guys suggest?

Since both Giel and I are low on time to work on this, and since missing
hwmon support on a system is not really a big deal (for most users) I suggest
that this patch is reverted until we find the time to do it properly.

Regards,

Hans

p.s.

I've already seen mails that you've dropped this patch from -mm, does that
mean it thas been removed from mainly too ? If not please remove it from
mainline / ask Linus to remove it.

Thanks.

Hans

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the
@ 2010-08-22 18:04                             ` Hans de Goede
  0 siblings, 0 replies; 159+ messages in thread
From: Hans de Goede @ 2010-08-22 18:04 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Giel van Schijndel, Laurens Leemans, Jonathan Cameron,
	Randy Dunlap, Jean Delvare, Mark Brown, Samuel Ortiz, lm-sensors,
	linux-kernel, linux-doc

Hi,

On 08/18/2010 08:24 PM, Andrew Morton wrote:
> On Fri, 13 Aug 2010 12:01:36 +0200
> Hans de Goede<hdegoede@redhat.com>  wrote:
>
>> Hi,
>>
>> On 08/10/2010 09:11 PM, Giel van Schijndel wrote:
>>> On Wed, Aug 04, 2010 at 01:36:22PM +0200, Hans de Goede wrote:
>>>> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
>>>>> Allow device probing to recognise the Fintek F71808E.
>>>>>
>>>>> Sysfs interface:
>>>>>     * Fan/pwm control is the same as for F71889FG
>>>>
>>>> My datasheet strongly disagrees with this ...
>>>
>>> I just noticed this patch was applied to mainline anyway.  Regardless, I
>>> will (try to) address these issues you raised.
>>>
>>> Right now however, I am prioritising personal stuff above this
>>> driver---bachelor's thesis and graduation presentation.  When finished
>>> with that (september) I'll allocate time to these issues again.
>>>
>>
>> I've send a mail directly to akpm asking for this to be removed, hopefully
>> this will help.
>
> It seems that I managed to muck up my paperwork and the patch was
> merged into mainline.
>
> We can revert it, or we can fix it up in place in time for 2.6.36.
> What do you guys suggest?

Since both Giel and I are low on time to work on this, and since missing
hwmon support on a system is not really a big deal (for most users) I suggest
that this patch is reverted until we find the time to do it properly.

Regards,

Hans

p.s.

I've already seen mails that you've dropped this patch from -mm, does that
mean it thas been removed from mainly too ? If not please remove it from
mainline / ask Linus to remove it.

Thanks.

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E
  2010-08-22 18:04                             ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Hans de Goede
@ 2010-08-22 18:28                               ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-22 18:28 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Andrew Morton, Laurens Leemans, Jonathan Cameron, Randy Dunlap,
	Jean Delvare, Mark Brown, Samuel Ortiz, lm-sensors, linux-kernel,
	linux-doc

[-- Attachment #1: Type: text/plain, Size: 445 bytes --]

On Sun, Aug 22, 2010 at 08:04:38PM +0200, Hans de Goede wrote:
> p.s.
> 
> I've already seen mails that you've dropped this patch from -mm, does that
> mean it thas been removed from mainly too ? If not please remove it from
> mainline / ask Linus to remove it.

Checking .../torvalds/linux-2.6.git you can see it's been reverted in
mainline (see commit f2e41e9).

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the
@ 2010-08-22 18:28                               ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-08-22 18:28 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Andrew Morton, Laurens Leemans, Jonathan Cameron, Randy Dunlap,
	Jean Delvare, Mark Brown, Samuel Ortiz, lm-sensors, linux-kernel,
	linux-doc


[-- Attachment #1.1: Type: text/plain, Size: 445 bytes --]

On Sun, Aug 22, 2010 at 08:04:38PM +0200, Hans de Goede wrote:
> p.s.
> 
> I've already seen mails that you've dropped this patch from -mm, does that
> mean it thas been removed from mainly too ? If not please remove it from
> mainline / ask Linus to remove it.

Checking .../torvalds/linux-2.6.git you can see it's been reverted in
mainline (see commit f2e41e9).

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-08-04 11:38                   ` [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Hans de Goede
@ 2010-10-02 22:59                       ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-10-02 22:59 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Laurens Leemans, Jonathan Cameron, Jean Delvare, Guenter Roeck,
	Andrew Morton, lm-sensors, linux-kernel, 597820

[-- Attachment #1: Type: text/plain, Size: 1171 bytes --]

On Wed, Aug 04, 2010 at 01:38:50PM +0200, Hans de Goede wrote:
> Ack!
> 
> Acked-by: Hans de Goede <hdegoede@redhat.com>
> 
> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
>> Sleep while acquiring a resource lock on the Super I/O port. This should
>> prevent collisions from causing the hardware probe to fail with -EBUSY.
>> 
>> Signed-off-by: Giel van Schijndel<me@mortis.eu>

Would anyone please apply this patch?  It's been sitting for quite some
time now collecting dust (none of that fictional bit-rot thus far
however).  If this patch needs to be resubmitted or requires me to poke
a specific individual please let me know (and what individual to poke).

FYI the Message-ID of that patch is:
<1280669455-31283-1-git-send-email-me@mortis.eu>

PS I've added Guenter Roeck and Andrew Morton to the CC list because
   between now and the original submission date they got appended to
   scripts/get_maintainer.pl's output.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel
--
"It would seem that perfection is attained not when no more can be
 added, but when no more can be removed."
  -- Antoine de Saint Exupéry

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource
@ 2010-10-02 22:59                       ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-10-02 22:59 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Laurens Leemans, Jonathan Cameron, Jean Delvare, Guenter Roeck,
	Andrew Morton, lm-sensors, linux-kernel, 597820


[-- Attachment #1.1: Type: text/plain, Size: 1171 bytes --]

On Wed, Aug 04, 2010 at 01:38:50PM +0200, Hans de Goede wrote:
> Ack!
> 
> Acked-by: Hans de Goede <hdegoede@redhat.com>
> 
> On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
>> Sleep while acquiring a resource lock on the Super I/O port. This should
>> prevent collisions from causing the hardware probe to fail with -EBUSY.
>> 
>> Signed-off-by: Giel van Schijndel<me@mortis.eu>

Would anyone please apply this patch?  It's been sitting for quite some
time now collecting dust (none of that fictional bit-rot thus far
however).  If this patch needs to be resubmitted or requires me to poke
a specific individual please let me know (and what individual to poke).

FYI the Message-ID of that patch is:
<1280669455-31283-1-git-send-email-me@mortis.eu>

PS I've added Guenter Roeck and Andrew Morton to the CC list because
   between now and the original submission date they got appended to
   scripts/get_maintainer.pl's output.

-- 
Met vriendelijke groet,
With kind regards,
Giel van Schijndel
--
"It would seem that perfection is attained not when no more can be
 added, but when no more can be removed."
  -- Antoine de Saint Exupéry

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-10-02 22:59                       ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource Giel van Schijndel
@ 2010-10-03  1:06                         ` Guenter Roeck
  -1 siblings, 0 replies; 159+ messages in thread
From: Guenter Roeck @ 2010-10-03  1:06 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Laurens Leemans, Jonathan Cameron, Jean Delvare,
	Andrew Morton, lm-sensors, linux-kernel, 597820

On Sat, Oct 02, 2010 at 06:59:58PM -0400, Giel van Schijndel wrote:
> On Wed, Aug 04, 2010 at 01:38:50PM +0200, Hans de Goede wrote:
> > Ack!
> > 
> > Acked-by: Hans de Goede <hdegoede@redhat.com>
> > 
> > On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
> >> Sleep while acquiring a resource lock on the Super I/O port. This should
> >> prevent collisions from causing the hardware probe to fail with -EBUSY.
> >> 
> >> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> 
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>

Jean, if it is ok with you, I can apply it to my tree.

I tried to find the patch on the web in downloadable form, but didn't find
the correct version of it. So it would be great if you could re-send it.

Thanks,
Guenter


^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource
@ 2010-10-03  1:06                         ` Guenter Roeck
  0 siblings, 0 replies; 159+ messages in thread
From: Guenter Roeck @ 2010-10-03  1:06 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Hans de Goede, Laurens Leemans, Jonathan Cameron, Jean Delvare,
	Andrew Morton, lm-sensors, linux-kernel, 597820

On Sat, Oct 02, 2010 at 06:59:58PM -0400, Giel van Schijndel wrote:
> On Wed, Aug 04, 2010 at 01:38:50PM +0200, Hans de Goede wrote:
> > Ack!
> > 
> > Acked-by: Hans de Goede <hdegoede@redhat.com>
> > 
> > On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
> >> Sleep while acquiring a resource lock on the Super I/O port. This should
> >> prevent collisions from causing the hardware probe to fail with -EBUSY.
> >> 
> >> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> 
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>

Jean, if it is ok with you, I can apply it to my tree.

I tried to find the patch on the web in downloadable form, but didn't find
the correct version of it. So it would be great if you could re-send it.

Thanks,
Guenter


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-10-03  1:06                         ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource Guenter Roeck
@ 2010-10-03  9:01                           ` Jean Delvare
  -1 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-10-03  9:01 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Giel van Schijndel, Hans de Goede, Laurens Leemans,
	Jonathan Cameron, Andrew Morton, lm-sensors, linux-kernel,
	597820

On Sat, 2 Oct 2010 18:06:35 -0700, Guenter Roeck wrote:
> On Sat, Oct 02, 2010 at 06:59:58PM -0400, Giel van Schijndel wrote:
> > On Wed, Aug 04, 2010 at 01:38:50PM +0200, Hans de Goede wrote:
> > > Ack!
> > > 
> > > Acked-by: Hans de Goede <hdegoede@redhat.com>
> > > 
> > > On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
> > >> Sleep while acquiring a resource lock on the Super I/O port. This should
> > >> prevent collisions from causing the hardware probe to fail with -EBUSY.
> > >> 
> > >> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> > 
> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
> 
> Jean, if it is ok with you, I can apply it to my tree.

I have no objection. I never had the time to look at these patches, and
won't have it any time soon. So I'm very happy if you can handle them.

> I tried to find the patch on the web in downloadable form, but didn't find
> the correct version of it. So it would be great if you could re-send it.

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource
@ 2010-10-03  9:01                           ` Jean Delvare
  0 siblings, 0 replies; 159+ messages in thread
From: Jean Delvare @ 2010-10-03  9:01 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Giel van Schijndel, Hans de Goede, Laurens Leemans,
	Jonathan Cameron, Andrew Morton, lm-sensors, linux-kernel,
	597820

On Sat, 2 Oct 2010 18:06:35 -0700, Guenter Roeck wrote:
> On Sat, Oct 02, 2010 at 06:59:58PM -0400, Giel van Schijndel wrote:
> > On Wed, Aug 04, 2010 at 01:38:50PM +0200, Hans de Goede wrote:
> > > Ack!
> > > 
> > > Acked-by: Hans de Goede <hdegoede@redhat.com>
> > > 
> > > On 08/01/2010 03:30 PM, Giel van Schijndel wrote:
> > >> Sleep while acquiring a resource lock on the Super I/O port. This should
> > >> prevent collisions from causing the hardware probe to fail with -EBUSY.
> > >> 
> > >> Signed-off-by: Giel van Schijndel<me@mortis.eu>
> > 
> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
> 
> Jean, if it is ok with you, I can apply it to my tree.

I have no objection. I never had the time to look at these patches, and
won't have it any time soon. So I'm very happy if you can handle them.

> I tried to find the patch on the web in downloadable form, but didn't find
> the correct version of it. So it would be great if you could re-send it.

-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

* [PATCH] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-10-03  1:06                         ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource Guenter Roeck
@ 2010-10-03 12:09                           ` Giel van Schijndel
  -1 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-10-03 12:09 UTC (permalink / raw)
  Cc: Laurens Leemans, Jonathan Cameron, Debian Bug #597820,
	Giel van Schijndel, Jean Delvare, Guenter Roeck, Hans de Goede,
	Andrew Morton, lm-sensors, linux-kernel

Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   32 +++++++++++++++++++-------------
 1 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 537841e..75afb3b 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -861,11 +861,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
 		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	default:
 		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
 		       (unsigned int)devid);
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
 		printk(KERN_WARNING DRVNAME ": Device not activated\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
 	*address = superio_inw(sioaddr, SIO_REG_ADDR);
 	if (*address == 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+		err = -ENODEV;
 		goto exit;
 	}
 	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
@@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


^ permalink raw reply related	[flat|nested] 159+ messages in thread

* [lm-sensors] [PATCH] hwmon: f71882fg: use a muxed resource lock for
@ 2010-10-03 12:09                           ` Giel van Schijndel
  0 siblings, 0 replies; 159+ messages in thread
From: Giel van Schijndel @ 2010-10-03 12:09 UTC (permalink / raw)
  Cc: Laurens Leemans, Jonathan Cameron, Debian Bug #597820,
	Giel van Schijndel, Jean Delvare, Guenter Roeck, Hans de Goede,
	Andrew Morton, lm-sensors, linux-kernel

Sleep while acquiring a resource lock on the Super I/O port. This should
prevent collisions from causing the hardware probe to fail with -EBUSY.

Signed-off-by: Giel van Schijndel <me@mortis.eu>
---
 drivers/hwmon/f71882fg.c |   32 +++++++++++++++++++-------------
 1 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 537841e..75afb3b 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev;
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
 static inline int superio_inw(int base, int reg);
-static inline void superio_enter(int base);
+static inline int superio_enter(int base);
 static inline void superio_select(int base, int ld);
 static inline void superio_exit(int base);
 
@@ -861,11 +861,20 @@ static int superio_inw(int base, int reg)
 	return val;
 }
 
-static inline void superio_enter(int base)
+static inline int superio_enter(int base)
 {
+	/* Don't step on other drivers' I/O space by accident */
+	if (!request_muxed_region(base, 2, DRVNAME)) {
+		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
+				base);
+		return -EBUSY;
+	}
+
 	/* according to the datasheet the key must be send twice! */
 	outb(SIO_UNLOCK_KEY, base);
 	outb(SIO_UNLOCK_KEY, base);
+
+	return 0;
 }
 
 static inline void superio_select(int base, int ld)
@@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld)
 static inline void superio_exit(int base)
 {
 	outb(SIO_LOCK_KEY, base);
+	release_region(base, 2);
 }
 
 static inline int fan_from_reg(u16 reg)
@@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev)
 static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	struct f71882fg_sio_data *sio_data)
 {
-	int err = -ENODEV;
 	u16 devid;
-
-	/* Don't step on other drivers' I/O space by accident */
-	if (!request_region(sioaddr, 2, DRVNAME)) {
-		printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
-				(int)sioaddr);
-		return -EBUSY;
-	}
-
-	superio_enter(sioaddr);
+	int err = superio_enter(sioaddr);
+	if (err)
+		return err;
 
 	devid = superio_inw(sioaddr, SIO_REG_MANID);
 	if (devid != SIO_FINTEK_ID) {
 		pr_debug(DRVNAME ": Not a Fintek device\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 	default:
 		printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
 		       (unsigned int)devid);
+		err = -ENODEV;
 		goto exit;
 	}
 
@@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 
 	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
 		printk(KERN_WARNING DRVNAME ": Device not activated\n");
+		err = -ENODEV;
 		goto exit;
 	}
 
 	*address = superio_inw(sioaddr, SIO_REG_ADDR);
 	if (*address = 0) {
 		printk(KERN_WARNING DRVNAME ": Base address not set\n");
+		err = -ENODEV;
 		goto exit;
 	}
 	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */
@@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
 		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
 	superio_exit(sioaddr);
-	release_region(sioaddr, 2);
 	return err;
 }
 
-- 
1.6.4.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 159+ messages in thread

* Re: [PATCH] hwmon: f71882fg: use a muxed resource lock for the Super I/O port
  2010-10-03 12:09                           ` [lm-sensors] [PATCH] hwmon: f71882fg: use a muxed resource lock for Giel van Schijndel
@ 2010-10-03 13:31                             ` Guenter Roeck
  -1 siblings, 0 replies; 159+ messages in thread
From: Guenter Roeck @ 2010-10-03 13:31 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Laurens Leemans, Jonathan Cameron, Debian Bug #597820,
	Jean Delvare, Hans de Goede, Andrew Morton, lm-sensors,
	linux-kernel

On Sun, Oct 03, 2010 at 08:09:49AM -0400, Giel van Schijndel wrote:
> Sleep while acquiring a resource lock on the Super I/O port. This should
> prevent collisions from causing the hardware probe to fail with -EBUSY.
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>

Applied.

Guenter

^ permalink raw reply	[flat|nested] 159+ messages in thread

* Re: [lm-sensors] [PATCH] hwmon: f71882fg: use a muxed resource lock
@ 2010-10-03 13:31                             ` Guenter Roeck
  0 siblings, 0 replies; 159+ messages in thread
From: Guenter Roeck @ 2010-10-03 13:31 UTC (permalink / raw)
  To: Giel van Schijndel
  Cc: Laurens Leemans, Jonathan Cameron, Debian Bug #597820,
	Jean Delvare, Hans de Goede, Andrew Morton, lm-sensors,
	linux-kernel

On Sun, Oct 03, 2010 at 08:09:49AM -0400, Giel van Schijndel wrote:
> Sleep while acquiring a resource lock on the Super I/O port. This should
> prevent collisions from causing the hardware probe to fail with -EBUSY.
> 
> Signed-off-by: Giel van Schijndel <me@mortis.eu>

Applied.

Guenter

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 159+ messages in thread

end of thread, other threads:[~2010-10-03 13:33 UTC | newest]

Thread overview: 159+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-23 14:12 [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Giel van Schijndel
2010-03-23 14:12 ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O regions Giel van Schijndel
2010-03-23 14:17 ` [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Giel van Schijndel
2010-03-23 14:17   ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
2010-03-23 23:12   ` [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for the Fintek F71808E Giel van Schijndel
2010-03-23 23:12     ` [lm-sensors] [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for the Giel van Schijndel
2010-03-23 23:12     ` [PATCH 2/4] hwmon: f71882fg: prepare for addition of watchdog support Giel van Schijndel
2010-03-23 23:12       ` [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition of Giel van Schijndel
2010-03-23 23:12       ` [PATCH 3/4] hwmon: f71882fg: add watchdog detection code Giel van Schijndel
2010-03-23 23:12         ` [lm-sensors] [PATCH 3/4] hwmon: f71882fg: add watchdog detection Giel van Schijndel
2010-03-23 23:12         ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Giel van Schijndel
2010-03-23 23:12           ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API Giel van Schijndel
2010-03-23 23:26           ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Giel van Schijndel
2010-03-23 23:26             ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
2010-03-24  8:37           ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Hans de Goede
2010-03-24  8:37             ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Hans de Goede
2010-03-24  9:36             ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Giel van Schijndel
2010-03-24  9:36               ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
2010-03-24 10:33               ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Hans de Goede
2010-03-24 10:33                 ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Hans de Goede
2010-03-24 15:35                 ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Giel van Schijndel
2010-03-24 15:35                   ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
2010-03-24 15:51                   ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Alan Cox
2010-03-24 15:51                     ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Alan Cox
2010-03-24 16:20                     ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Hans de Goede
2010-03-24 16:20                       ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Hans de Goede
2010-03-24 20:35                       ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Giel van Schijndel
2010-03-24 20:35                         ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
2010-04-25 21:20                         ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Jim Cromie
2010-04-25 21:20                           ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Jim Cromie
2010-03-25  8:54                     ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Giel van Schijndel
2010-03-25  8:54                       ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
2010-03-25 10:40                       ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Giel van Schijndel
2010-03-25 10:40                         ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Giel van Schijndel
2010-03-25 12:50                         ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Alan Cox
2010-03-25 12:50                           ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Alan Cox
2010-03-25 13:06                           ` [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog API for F71808E and F71889 Hans de Goede
2010-03-25 13:06                             ` [lm-sensors] [PATCH 4/4] [RFC] hwmon: f71882fg: Add watchdog Hans de Goede
2010-03-25 13:17                           ` [PATCH 1/3] resource: shared I/O region support Giel van Schijndel
2010-03-25 13:17                             ` [lm-sensors] " Giel van Schijndel
2010-03-25 13:17                             ` [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Giel van Schijndel
2010-03-25 13:17                               ` [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock Giel van Schijndel
2010-03-25 13:17                               ` [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E Giel van Schijndel
2010-03-25 13:17                                 ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog Giel van Schijndel
2010-03-30  9:06                                 ` [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E Giel van Schijndel
2010-03-30  9:06                                   ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Giel van Schijndel
2010-05-20  7:52                                   ` [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E Wim Van Sebroeck
2010-05-20  7:52                                     ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Wim Van Sebroeck
2010-05-25 21:08                                     ` [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E Giel van Schijndel
2010-05-25 21:08                                       ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Giel van Schijndel
2010-05-26  7:38                                       ` [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E Wim Van Sebroeck
2010-05-26  7:38                                         ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Wim Van Sebroeck
2010-07-31 21:36                                         ` [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E Giel van Schijndel
2010-07-31 21:36                                           ` [lm-sensors] [PATCH 3/3] [RFC] watchdog: f71808e_wdt: new Giel van Schijndel
2010-03-25 21:10                               ` [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Hans de Goede
2010-03-25 21:10                                 ` [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource Hans de Goede
2010-04-25 10:35                               ` [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Giel van Schijndel
2010-04-25 10:35                                 ` [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource Giel van Schijndel
2010-07-31 21:21                                 ` [PATCH 2/3] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Giel van Schijndel
2010-07-31 21:21                                   ` [lm-sensors] [PATCH 2/3] hwmon: f71882fg: use a muxed resource Giel van Schijndel
2010-03-25 15:57                             ` [PATCH 1/3] resource: shared I/O region support Alan Cox
2010-03-25 15:57                               ` [lm-sensors] " Alan Cox
2010-03-25 18:03                               ` Giel van Schijndel
2010-03-25 18:03                                 ` [lm-sensors] " Giel van Schijndel
2010-03-25 18:16                                 ` Alan Cox
2010-03-25 18:16                                   ` [lm-sensors] " Alan Cox
2010-03-29  8:18                                   ` Giel van Schijndel
2010-03-29  8:18                                     ` [lm-sensors] " Giel van Schijndel
2010-03-29 16:07                                     ` Jesse Barnes
2010-03-29 16:07                                       ` [lm-sensors] " Jesse Barnes
2010-03-29 17:38                                       ` Giel van Schijndel
2010-03-29 17:38                                         ` [lm-sensors] " Giel van Schijndel
2010-03-29 17:44                                         ` Giel van Schijndel
2010-03-29 17:44                                           ` [lm-sensors] " Giel van Schijndel
2010-03-29 17:45                                         ` H. Peter Anvin
2010-03-29 17:45                                           ` [lm-sensors] " H. Peter Anvin
2010-03-29 18:06                                           ` Jesse Barnes
2010-03-29 18:06                                             ` [lm-sensors] " Jesse Barnes
2010-03-29 18:17                                             ` H. Peter Anvin
2010-03-29 18:17                                               ` [lm-sensors] " H. Peter Anvin
2010-03-29 18:29                                             ` Alan Cox
2010-03-29 18:29                                               ` [lm-sensors] " Alan Cox
2010-04-02 20:29                                               ` Jesse Barnes
2010-04-02 20:29                                                 ` [lm-sensors] " Jesse Barnes
2010-03-29 18:39                                           ` Alan Cox
2010-03-29 18:39                                             ` [lm-sensors] " Alan Cox
2010-03-29 18:56                                             ` H. Peter Anvin
2010-03-29 18:56                                               ` [lm-sensors] " H. Peter Anvin
2010-03-29 17:59                                         ` Jesse Barnes
2010-03-29 17:59                                           ` [lm-sensors] " Jesse Barnes
2010-03-29 17:59                                         ` Jesse Barnes
2010-03-29 17:59                                           ` [lm-sensors] " Jesse Barnes
2010-03-24  8:26       ` [PATCH 2/4] hwmon: f71882fg: prepare for addition of watchdog support Hans de Goede
2010-03-24  8:26         ` [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition Hans de Goede
2010-03-24  8:36       ` [PATCH 2/4] hwmon: f71882fg: prepare for addition of watchdog support Hans de Goede
2010-03-24  8:36         ` [lm-sensors] [PATCH 2/4] hwmon: f71882fg: prepare for addition Hans de Goede
2010-03-24  8:25     ` [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for the Fintek F71808E Hans de Goede
2010-03-24  8:25       ` [lm-sensors] [PATCH 1/4] [RFC] hwmon: f71882fg: Add support for Hans de Goede
2010-03-24  9:23       ` [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E Giel van Schijndel
2010-03-24  9:23         ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Giel van Schijndel
2010-03-24 10:31         ` [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E Hans de Goede
2010-03-24 10:31           ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Hans de Goede
2010-07-31 23:31           ` [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E Giel van Schijndel
2010-07-31 23:31             ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Giel van Schijndel
2010-08-01  6:12             ` [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E Hans de Goede
2010-08-01  6:12               ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Hans de Goede
2010-08-01 13:22               ` [PATCH 1/4] hwmon: f71882fg: Add support for the Fintek F71808E Giel van Schijndel
2010-08-01 13:22                 ` [lm-sensors] [PATCH 1/4] hwmon: f71882fg: Add support for the Giel van Schijndel
2010-08-01 13:30                 ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Giel van Schijndel
2010-08-01 13:30                   ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Fintek Giel van Schijndel
2010-08-04 11:36                   ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Hans de Goede
2010-08-04 15:44                     ` Giel van Schijndel
2010-08-13 10:56                       ` Hans de Goede
2010-08-13 10:56                         ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Hans de Goede
2010-08-10 19:11                     ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Giel van Schijndel
2010-08-10 19:11                       ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Giel van Schijndel
2010-08-13 10:01                       ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Hans de Goede
2010-08-13 10:01                         ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Hans de Goede
2010-08-18 18:24                         ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Andrew Morton
2010-08-18 18:24                           ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Andrew Morton
2010-08-22 18:04                           ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Hans de Goede
2010-08-22 18:04                             ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Hans de Goede
2010-08-22 18:28                             ` [PATCH] hwmon: f71882fg: Add support for the Fintek F71808E Giel van Schijndel
2010-08-22 18:28                               ` [lm-sensors] [PATCH] hwmon: f71882fg: Add support for the Giel van Schijndel
2010-08-01 13:30                 ` [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Giel van Schijndel
2010-08-01 13:30                   ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock Giel van Schijndel
2010-08-01 13:30                   ` [PATCH 2/2] watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E and F71882FG Giel van Schijndel
2010-08-01 13:30                     ` Giel van Schijndel
2010-08-04 11:38                   ` [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Hans de Goede
2010-10-02 22:59                     ` Giel van Schijndel
2010-10-02 22:59                       ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource Giel van Schijndel
2010-10-03  1:06                       ` [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Guenter Roeck
2010-10-03  1:06                         ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource Guenter Roeck
2010-10-03  9:01                         ` [PATCH 1/2] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Jean Delvare
2010-10-03  9:01                           ` [lm-sensors] [PATCH 1/2] hwmon: f71882fg: use a muxed resource Jean Delvare
2010-10-03 12:09                         ` [PATCH] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Giel van Schijndel
2010-10-03 12:09                           ` [lm-sensors] [PATCH] hwmon: f71882fg: use a muxed resource lock for Giel van Schijndel
2010-10-03 13:31                           ` [PATCH] hwmon: f71882fg: use a muxed resource lock for the Super I/O port Guenter Roeck
2010-10-03 13:31                             ` [lm-sensors] [PATCH] hwmon: f71882fg: use a muxed resource lock Guenter Roeck
2010-03-23 23:01 ` [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Giel van Schijndel
2010-03-23 23:01   ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
2010-03-24  8:14 ` [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Hans de Goede
2010-03-24  8:14   ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Hans de Goede
2010-03-24  8:46   ` [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Giel van Schijndel
2010-03-24  8:46     ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
2010-03-24  9:09     ` [PATCH] hwmon: f71882fg: code cleanup Giel van Schijndel
2010-03-24  9:09       ` [lm-sensors] " Giel van Schijndel
2010-03-24 12:54       ` Jean Delvare
2010-03-24 12:54         ` [lm-sensors] " Jean Delvare
2010-03-24  9:09     ` [PATCH] hwmon: f71882fg: acquire I/O regions while we're working with them Giel van Schijndel
2010-03-24  9:09       ` [lm-sensors] [PATCH] hwmon: f71882fg: acquire I/O regions while Giel van Schijndel
2010-03-24  9:28     ` [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Jean Delvare
2010-03-24  9:28       ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Jean Delvare
2010-03-24  9:29 ` [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Jean Delvare
2010-03-24  9:29   ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Jean Delvare
2010-03-24  9:34   ` [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Giel van Schijndel
2010-03-24  9:34     ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Giel van Schijndel
2010-03-24 12:54     ` [PATCH] hwmon: f71882fg: properly acquire I/O regions while probing Jean Delvare
2010-03-24 12:54       ` [lm-sensors] [PATCH] hwmon: f71882fg: properly acquire I/O Jean Delvare

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.