mirror of https://gitee.com/openkylin/linux.git
watchdog: iTCO_wdt: Add support for TCO on Intel Sunrisepoint
The revision of the watchdog hardware in Sunrisepoint necessitates a new "version" inside the TCO watchdog driver because some of the register layouts have changed. Also update the Kconfig entry to select both the LPC and SMBus drivers since the TCO device is on the SMBus in Sunrisepoint. Signed-off-by: Matt Fleming <matt.fleming@intel.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Lee Jones <lee.jones@linaro.org>
This commit is contained in:
parent
9424693035
commit
2a7a0e9bf7
|
@ -797,7 +797,8 @@ config ITCO_WDT
|
||||||
tristate "Intel TCO Timer/Watchdog"
|
tristate "Intel TCO Timer/Watchdog"
|
||||||
depends on (X86 || IA64) && PCI
|
depends on (X86 || IA64) && PCI
|
||||||
select WATCHDOG_CORE
|
select WATCHDOG_CORE
|
||||||
select LPC_ICH
|
select LPC_ICH if !EXPERT
|
||||||
|
select I2C_I801 if !EXPERT
|
||||||
---help---
|
---help---
|
||||||
Hardware driver for the intel TCO timer based watchdog devices.
|
Hardware driver for the intel TCO timer based watchdog devices.
|
||||||
These drivers are included in the Intel 82801 I/O Controller
|
These drivers are included in the Intel 82801 I/O Controller
|
||||||
|
|
|
@ -145,59 +145,67 @@ static inline unsigned int ticks_to_seconds(int ticks)
|
||||||
return iTCO_wdt_private.iTCO_version == 3 ? ticks : (ticks * 6) / 10;
|
return iTCO_wdt_private.iTCO_version == 3 ? ticks : (ticks * 6) / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32 no_reboot_bit(void)
|
||||||
|
{
|
||||||
|
u32 enable_bit;
|
||||||
|
|
||||||
|
switch (iTCO_wdt_private.iTCO_version) {
|
||||||
|
case 3:
|
||||||
|
enable_bit = 0x00000010;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
enable_bit = 0x00000020;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
|
enable_bit = 0x00000002;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return enable_bit;
|
||||||
|
}
|
||||||
|
|
||||||
static void iTCO_wdt_set_NO_REBOOT_bit(void)
|
static void iTCO_wdt_set_NO_REBOOT_bit(void)
|
||||||
{
|
{
|
||||||
u32 val32;
|
u32 val32;
|
||||||
|
|
||||||
/* Set the NO_REBOOT bit: this disables reboots */
|
/* Set the NO_REBOOT bit: this disables reboots */
|
||||||
if (iTCO_wdt_private.iTCO_version == 3) {
|
if (iTCO_wdt_private.iTCO_version >= 2) {
|
||||||
val32 = readl(iTCO_wdt_private.gcs_pmc);
|
val32 = readl(iTCO_wdt_private.gcs_pmc);
|
||||||
val32 |= 0x00000010;
|
val32 |= no_reboot_bit();
|
||||||
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_pmc);
|
writel(val32, iTCO_wdt_private.gcs_pmc);
|
||||||
} else if (iTCO_wdt_private.iTCO_version == 1) {
|
} else if (iTCO_wdt_private.iTCO_version == 1) {
|
||||||
pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
|
pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
|
||||||
val32 |= 0x00000002;
|
val32 |= no_reboot_bit();
|
||||||
pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
|
pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iTCO_wdt_unset_NO_REBOOT_bit(void)
|
static int iTCO_wdt_unset_NO_REBOOT_bit(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
u32 enable_bit = no_reboot_bit();
|
||||||
u32 val32;
|
u32 val32 = 0;
|
||||||
|
|
||||||
/* Unset the NO_REBOOT bit: this enables reboots */
|
/* Unset the NO_REBOOT bit: this enables reboots */
|
||||||
if (iTCO_wdt_private.iTCO_version == 3) {
|
if (iTCO_wdt_private.iTCO_version >= 2) {
|
||||||
val32 = readl(iTCO_wdt_private.gcs_pmc);
|
val32 = readl(iTCO_wdt_private.gcs_pmc);
|
||||||
val32 &= 0xffffffef;
|
val32 &= ~enable_bit;
|
||||||
writel(val32, iTCO_wdt_private.gcs_pmc);
|
writel(val32, iTCO_wdt_private.gcs_pmc);
|
||||||
|
|
||||||
val32 = readl(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_pmc);
|
|
||||||
|
|
||||||
val32 = readl(iTCO_wdt_private.gcs_pmc);
|
|
||||||
if (val32 & 0x00000020)
|
|
||||||
ret = -EIO;
|
|
||||||
} else if (iTCO_wdt_private.iTCO_version == 1) {
|
} else if (iTCO_wdt_private.iTCO_version == 1) {
|
||||||
pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
|
pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
|
||||||
val32 &= 0xfffffffd;
|
val32 &= ~enable_bit;
|
||||||
pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
|
pci_write_config_dword(iTCO_wdt_private.pdev, 0xd4, val32);
|
||||||
|
|
||||||
pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
|
pci_read_config_dword(iTCO_wdt_private.pdev, 0xd4, &val32);
|
||||||
if (val32 & 0x00000002)
|
|
||||||
ret = -EIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret; /* returns: 0 = OK, -EIO = Error */
|
if (val32 & enable_bit)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iTCO_wdt_start(struct watchdog_device *wd_dev)
|
static int iTCO_wdt_start(struct watchdog_device *wd_dev)
|
||||||
|
@ -503,12 +511,21 @@ static int iTCO_wdt_probe(struct platform_device *dev)
|
||||||
pdata->name, pdata->version, (u64)TCOBASE);
|
pdata->name, pdata->version, (u64)TCOBASE);
|
||||||
|
|
||||||
/* Clear out the (probably old) status */
|
/* Clear out the (probably old) status */
|
||||||
if (iTCO_wdt_private.iTCO_version == 3) {
|
switch (iTCO_wdt_private.iTCO_version) {
|
||||||
|
case 4:
|
||||||
|
outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */
|
||||||
|
outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
outl(0x20008, TCO1_STS);
|
outl(0x20008, TCO1_STS);
|
||||||
} else {
|
break;
|
||||||
|
case 2:
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */
|
outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */
|
||||||
outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */
|
outw(0x0002, TCO2_STS); /* Clear SECOND_TO_STS bit */
|
||||||
outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */
|
outw(0x0004, TCO2_STS); /* Clear BOOT_STS bit */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
iTCO_wdt_watchdog_dev.bootstatus = 0;
|
iTCO_wdt_watchdog_dev.bootstatus = 0;
|
||||||
|
|
Loading…
Reference in New Issue