--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -128,6 +128,7 @@ enum iTCO_chipsets {
 	TCO_DH89XXCC,	/* DH89xxCC */
 	TCO_PPT,	/* Panther Point */
 	TCO_LPT,	/* Lynx Point */
+	TCO_AVN,	/* Avoton */
 };
 
 static struct {
@@ -192,6 +193,7 @@ static struct {
 	{"DH89xxCC", 2},
 	{"Panther Point", 2},
 	{"Lynx Point", 2},
+	{"Avoton", 3},
 	{NULL, 0}
 };
 
@@ -334,6 +336,10 @@ static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = {
 	{ PCI_VDEVICE(INTEL, 0x1e5d), TCO_PPT},
 	{ PCI_VDEVICE(INTEL, 0x1e5e), TCO_PPT},
 	{ PCI_VDEVICE(INTEL, 0x1e5f), TCO_PPT},
+	{ PCI_VDEVICE(INTEL, 0x1f38), TCO_AVN},
+	{ PCI_VDEVICE(INTEL, 0x1f39), TCO_AVN},
+	{ PCI_VDEVICE(INTEL, 0x1f3a), TCO_AVN},
+	{ PCI_VDEVICE(INTEL, 0x1f3b), TCO_AVN},
 	{ PCI_VDEVICE(INTEL, 0x8c40), TCO_LPT},
 	{ PCI_VDEVICE(INTEL, 0x8c41), TCO_LPT},
 	{ PCI_VDEVICE(INTEL, 0x8c42), TCO_LPT},
@@ -394,8 +400,12 @@ static struct {		/* this is private data for the iTCO_wdt device */
 	unsigned int iTCO_version;
 	/* The device's ACPIBASE address (TCOBASE = ACPIBASE+0x60) */
 	unsigned long ACPIBASE;
-	/* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/
-	unsigned long __iomem *gcs;
+	/*
+	 * NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2),
+	 * or memory-mapped PMC register bit 4 (TCO version 3).
+	 */
+	unsigned long __iomem *gcs_pmc;
+
 	/* the lock for io operations */
 	spinlock_t io_lock;
 	/* the PCI-device */
@@ -428,11 +438,19 @@ MODULE_PARM_DESC(turn_SMI_watchdog_clear_off,
  * Some TCO specific functions
  */
 
-static inline unsigned int seconds_to_ticks(int seconds)
+/*
+ * The iTCO v1 and v2's internal timer is stored as ticks which decrement
+ * every 0.6 seconds.  v3's internal timer is stored as seconds (some
+ * datasheets incorrectly state 0.6 seconds).
+ */
+static inline unsigned int seconds_to_ticks(int secs)
+{
+	return iTCO_wdt_private.iTCO_version == 3 ? secs : (secs * 10) / 6;
+}
+
+static inline unsigned int ticks_to_seconds(int ticks)
 {
-	/* the internal timer is stored as ticks which decrement
-	 * every 0.6 seconds */
-	return (seconds * 10) / 6;
+	return iTCO_wdt_private.iTCO_version == 3 ? ticks : (ticks * 6) / 10;
 }
 
 static void iTCO_wdt_set_NO_REBOOT_bit(void)
@@ -440,10 +458,14 @@ static void iTCO_wdt_set_NO_REBOOT_bit(void)
 	u32 val32;
 
 	/* Set the NO_REBOOT bit: this disables reboots */
-	if (iTCO_wdt_private.iTCO_version == 2) {
-		val32 = readl(iTCO_wdt_private.gcs);
+	if (iTCO_wdt_private.iTCO_version == 3) {
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
+		val32 |= 0x00000010;
+		writel(val32, iTCO_wdt_private.gcs_pmc);
+	} else if (iTCO_wdt_private.iTCO_version >= 2) {
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
 		val32 |= 0x00000020;
-		writel(val32, iTCO_wdt_private.gcs);
+		writel(val32, iTCO_wdt_private.gcs_pmc);
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
 		pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
 		val32 |= 0x00000002;
@@ -457,12 +479,20 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void)
 	u32 val32;
 
 	/* Unset the NO_REBOOT bit: this enables reboots */
-	if (iTCO_wdt_private.iTCO_version == 2) {
-		val32 = readl(iTCO_wdt_private.gcs);
+	if (iTCO_wdt_private.iTCO_version == 3) {
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
+		val32 &= 0xffffffef;
+		writel(val32, iTCO_wdt_private.gcs_pmc);
+
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
+		if (val32 & 0x00000010)
+			ret = -EIO;
+	} else if (iTCO_wdt_private.iTCO_version == 2) {
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
 		val32 &= 0xffffffdf;
-		writel(val32, iTCO_wdt_private.gcs);
+		writel(val32, iTCO_wdt_private.gcs_pmc);
 
-		val32 = readl(iTCO_wdt_private.gcs);
+		val32 = readl(iTCO_wdt_private.gcs_pmc);
 		if (val32 & 0x00000020)
 			ret = -EIO;
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
@@ -496,7 +526,7 @@ static int iTCO_wdt_start(void)
 
 	/* Force the timer to its reload value by writing to the TCO_RLD
 	   register */
-	if (iTCO_wdt_private.iTCO_version == 2)
+	if (iTCO_wdt_private.iTCO_version >= 2)
 		outw(0x01, TCO_RLD);
 	else if (iTCO_wdt_private.iTCO_version == 1)
 		outb(0x01, TCO_RLD);
@@ -544,9 +574,9 @@ static int iTCO_wdt_keepalive(void)
 	iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat);
 
 	/* Reload the timer by writing to the TCO Timer Counter register */
-	if (iTCO_wdt_private.iTCO_version == 2)
+	if (iTCO_wdt_private.iTCO_version >= 2) {
 		outw(0x01, TCO_RLD);
-	else if (iTCO_wdt_private.iTCO_version == 1) {
+	} else if (iTCO_wdt_private.iTCO_version == 1) {
 		/* Reset the timeout status bit so that the timer
 		 * needs to count down twice again before rebooting */
 		outw(0x0008, TCO1_STS);	/* write 1 to clear bit */
@@ -574,14 +604,14 @@ static int iTCO_wdt_set_heartbeat(int t)
 	/* "Values of 0h-3h are ignored and should not be attempted" */
 	if (tmrval < 0x04)
 		return -EINVAL;
-	if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) ||
+	if (((iTCO_wdt_private.iTCO_version >= 2) && (tmrval > 0x3ff)) ||
 	    ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f)))
 		return -EINVAL;
 
 	iTCO_vendor_pre_set_heartbeat(tmrval);
 
 	/* Write new heartbeat to watchdog */
-	if (iTCO_wdt_private.iTCO_version == 2) {
+	if (iTCO_wdt_private.iTCO_version >= 2) {
 		spin_lock(&iTCO_wdt_private.io_lock);
 		val16 = inw(TCOv2_TMR);
 		val16 &= 0xfc00;
@@ -615,13 +645,13 @@ static int iTCO_wdt_get_timeleft(int *time_left)
 	unsigned char val8;
 
 	/* read the TCO Timer */
-	if (iTCO_wdt_private.iTCO_version == 2) {
+	if (iTCO_wdt_private.iTCO_version >= 2) {
 		spin_lock(&iTCO_wdt_private.io_lock);
 		val16 = inw(TCO_RLD);
 		val16 &= 0x3ff;
 		spin_unlock(&iTCO_wdt_private.io_lock);
 
-		*time_left = (val16 * 6) / 10;
+		*time_left = ticks_to_seconds(val16);
 	} else if (iTCO_wdt_private.iTCO_version == 1) {
 		spin_lock(&iTCO_wdt_private.io_lock);
 		val8 = inb(TCO_RLD);
@@ -630,7 +660,7 @@ static int iTCO_wdt_get_timeleft(int *time_left)
 			val8 += (inb(TCOv1_TMR) & 0x3f);
 		spin_unlock(&iTCO_wdt_private.io_lock);
 
-		*time_left = (val8 * 6) / 10;
+		*time_left = ticks_to_seconds(val8);
 	} else
 		return -EINVAL;
 	return 0;
@@ -784,6 +814,24 @@ static struct miscdevice iTCO_wdt_miscdev = {
 };
 
 /*
+ * From patch for Avoton/Rangeley, enable PMC space; here rather
+ * than where it is in newer kernels to avoid patch problems
+ * We don't need all the functionality related to newer kernels,
+ * so comment out a  lot (keeping it for reference).
+ */
+static void
+lpc_ich_enable_pmc_space (struct pci_dev *dev)
+{
+	/*  struct lpc_ich_priv *priv = pci_get_drvdata (dev); */
+	u8 reg_save;
+
+	pci_read_config_byte (dev, /* priv->actrl_pbase */0x44, &reg_save);
+	pci_write_config_byte (dev, /* priv->actrl_pbase */0x44, reg_save | 0x2);
+
+	/* priv->actrl_pbase_save = reg_save; */
+}
+
+/*
  *	Init & exit routines
  */
 
@@ -810,13 +858,16 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
 	}
 	iTCO_wdt_private.iTCO_version =
 			iTCO_chipset_info[ent->driver_data].iTCO_version;
+	if (iTCO_wdt_private.iTCO_version == 3)
 	iTCO_wdt_private.ACPIBASE = base_address;
 	iTCO_wdt_private.pdev = pdev;
 
-	/* Get the Memory-Mapped GCS register, we need it for the
-	   NO_REBOOT flag (TCO v2). To get access to it you have to
-	   read RCBA from PCI Config space 0xf0 and use it as base.
-	   GCS = RCBA + ICH6_GCS(0x3410). */
+	/*
+	 * Get the Memory-Mapped GCS or PMC register, we need it for the
+	 * NO_REBOOT flag (TCO v2 and v3).
+	 * v2: read RCBA from PCI Config space 0xf0 and use it as base.
+	 *  GCS = RCBA + ICH6_GCS(0x3410).
+	 */
 	if (iTCO_wdt_private.iTCO_version == 2) {
 		pci_read_config_dword(pdev, 0xf0, &base_address);
 		if ((base_address & 1) == 0) {
@@ -826,7 +877,19 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
 			goto out;
 		}
 		RCBA = base_address & 0xffffc000;
-		iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4);
+		iTCO_wdt_private.gcs_pmc = ioremap((RCBA + 0x3410), 4);
+	}
+	else if (iTCO_wdt_private.iTCO_version == 3) {
+		/*
+		 * comes from ACPI, in PMC space.  driver resources
+		 * changed a lot in this area from our 3.2 kernel to
+		 * kernel where v3 support was added.  0x44 is ACPICTRL_PMBASE,
+		 * 0x8 is ACPI_PMC_OFF.
+		 */
+		lpc_ich_enable_pmc_space (pdev);
+		pci_read_config_dword(pdev, 0x44, &base_address);
+		base_address &= 0xfffffe00;
+		iTCO_wdt_private.gcs_pmc = ioremap(base_address + 0x8, 4);
 	}
 
 	/* Check chipset's NO_REBOOT bit */
@@ -871,9 +934,13 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
 			TCOBASE);
 
 	/* Clear out the (probably old) status */
-	outw(0x0008, TCO1_STS);	/* Clear the Time Out Status bit */
-	outw(0x0002, TCO2_STS);	/* Clear SECOND_TO_STS bit */
-	outw(0x0004, TCO2_STS);	/* Clear BOOT_STS bit */
+	if (iTCO_wdt_private.iTCO_version == 3) {
+		outl(0x20008, TCO1_STS);
+	} else {
+		outw(0x0008, TCO1_STS);	/* Clear the Time Out Status bit */
+		outw(0x0002, TCO2_STS);	/* Clear SECOND_TO_STS bit */
+		outw(0x0004, TCO2_STS);	/* Clear BOOT_STS bit */
+	}
 
 	/* Make sure the watchdog is not running */
 	iTCO_wdt_stop();
@@ -904,8 +971,8 @@ unreg_region:
 unreg_smi_en:
 	release_region(SMI_EN, 4);
 out_unmap:
-	if (iTCO_wdt_private.iTCO_version == 2)
-		iounmap(iTCO_wdt_private.gcs);
+	if (iTCO_wdt_private.iTCO_version >= 2)
+		iounmap(iTCO_wdt_private.gcs_pmc);
 out:
 	iTCO_wdt_private.ACPIBASE = 0;
 	return ret;
@@ -921,8 +988,8 @@ static void __devexit iTCO_wdt_cleanup(void)
 	misc_deregister(&iTCO_wdt_miscdev);
 	release_region(TCOBASE, 0x20);
 	release_region(SMI_EN, 4);
-	if (iTCO_wdt_private.iTCO_version == 2)
-		iounmap(iTCO_wdt_private.gcs);
+	if (iTCO_wdt_private.iTCO_version >= 2)
+		iounmap(iTCO_wdt_private.gcs_pmc);
 	pci_dev_put(iTCO_wdt_private.pdev);
 	iTCO_wdt_private.ACPIBASE = 0;
 }
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
new file mode 100644
index 0000000..8f541b9
