You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck:
"Core:
- min and max timeout improvements, WDOG_HW_RUNNING improvements,
status funtionality
- Add a device managed API for watchdog_register_device()
New watchdog drivers:
- Aspeed SoCs
- Maxim PMIC MAX77620
- Amlogic Meson GXBB SoC
Enhancements:
- support for the r8a7796 watchdog device
- support for F81866 watchdog device
- support for 5th variation of Apollo Lake
- support for MCP78S chipset
- clean-up of softdog.c watchdog device driver
- pic32-wdt and pic32-dmt fixes
- Documentation/watchdog: watchdog-test improvements
- several other fixes and improvements"
* git://www.linux-watchdog.org/linux-watchdog: (50 commits)
watchdog: gpio_wdt: Fix missing platform_set_drvdata() in gpio_wdt_probe()
watchdog: core: Clear WDOG_HW_RUNNING before calling the stop function
watchdog: core: Fix error handling of watchdog_dev_init()
watchdog: pic32-wdt: Fix return value check in pic32_wdt_drv_probe()
watchdog: pic32-dmt: Remove .owner field for driver
watchdog: pic32-wdt: Remove .owner field for driver
watchdog: renesas-wdt: Add support for the r8a7796 wdt
Documentation/watchdog: check return value for magic close
watchdog: sbsa: Drop status function
watchdog: Implement status function in watchdog core
watchdog: tangox: Set max_hw_heartbeat_ms instead of max_timeout
watchdog: change watchdog_need_worker logic
watchdog: add support for MCP78S chipset in nv_tco
watchdog: bcm2835_wdt: remove redundant ->set_timeout callback
watchdog: bcm2835_wdt: constify _ops and _info structures
dt-bindings: watchdog: Add Meson GXBB Watchdog bindings
watchdog: Add Meson GXBB Watchdog Driver
watchdog: qcom: configure BARK time in addition to BITE time
watchdog: qcom: add option for standalone watchdog not in timer block
watchdog: qcom: update device tree bindings
...
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
Aspeed Watchdog Timer
|
||||
|
||||
Required properties:
|
||||
- compatible: must be one of:
|
||||
- "aspeed,ast2400-wdt"
|
||||
- "aspeed,ast2500-wdt"
|
||||
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region
|
||||
|
||||
Example:
|
||||
|
||||
wdt1: watchdog@1e785000 {
|
||||
compatible = "aspeed,ast2400-wdt";
|
||||
reg = <0x1e785000 0x1c>;
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
Meson GXBB SoCs Watchdog timer
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "amlogic,meson-gxbb-wdt"
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
- clocks : Should be a phandle to the Watchdog clock source, for GXBB the xtal
|
||||
is the default clock source.
|
||||
|
||||
Example:
|
||||
|
||||
wdt: watchdog@98d0 {
|
||||
compatible = "amlogic,meson-gxbb-wdt";
|
||||
reg = <0 0x98d0 0x0 0x10>;
|
||||
clocks = <&xtal>;
|
||||
};
|
||||
@@ -7,6 +7,10 @@ Required properties :
|
||||
"qcom,kpss-wdt-msm8960"
|
||||
"qcom,kpss-wdt-apq8064"
|
||||
"qcom,kpss-wdt-ipq8064"
|
||||
"qcom,kpss-wdt-ipq4019"
|
||||
"qcom,kpss-timer"
|
||||
"qcom,scss-timer"
|
||||
"qcom,kpss-wdt"
|
||||
|
||||
- reg : shall contain base register location and length
|
||||
- clocks : shall contain the input clock
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
Renesas Watchdog Timer (WDT) Controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "renesas,r8a7795-wdt", or "renesas,rcar-gen3-wdt"
|
||||
- compatible : Should be "renesas,<soctype>-wdt", and
|
||||
"renesas,rcar-gen3-wdt" as fallback.
|
||||
Examples with soctypes are:
|
||||
- "renesas,r8a7795-wdt" (R-Car H3)
|
||||
- "renesas,r8a7796-wdt" (R-Car M3-W)
|
||||
|
||||
When compatible with the generic version, nodes must list the SoC-specific
|
||||
version corresponding to the platform first, followed by the generic
|
||||
|
||||
@@ -357,3 +357,6 @@ SLAVE DMA ENGINE
|
||||
|
||||
SPI
|
||||
devm_spi_register_master()
|
||||
|
||||
WATCHDOG
|
||||
devm_watchdog_register_device()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Last reviewed: 04/04/2016
|
||||
Last reviewed: 05/20/2016
|
||||
|
||||
HPE iLO NMI Watchdog Driver
|
||||
NMI sourcing for iLO based ProLiant Servers
|
||||
Documentation and Driver by
|
||||
Thomas Mingarelli <thomas.mingarelli@hpe.com>
|
||||
Thomas Mingarelli
|
||||
|
||||
The HPE iLO NMI Watchdog driver is a kernel module that provides basic
|
||||
watchdog functionality and the added benefit of NMI sourcing. Both the
|
||||
@@ -95,4 +95,3 @@ Last reviewed: 04/04/2016
|
||||
|
||||
|
||||
-- Tom Mingarelli
|
||||
(thomas.mingarelli@hpe.com)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Watchdog Driver Test Program
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include <linux/watchdog.h>
|
||||
|
||||
int fd;
|
||||
const char v = 'V';
|
||||
|
||||
/*
|
||||
* This function simply sends an IOCTL to the driver, which in turn ticks
|
||||
@@ -23,6 +25,7 @@ static void keep_alive(void)
|
||||
{
|
||||
int dummy;
|
||||
|
||||
printf(".");
|
||||
ioctl(fd, WDIOC_KEEPALIVE, &dummy);
|
||||
}
|
||||
|
||||
@@ -33,8 +36,13 @@ static void keep_alive(void)
|
||||
|
||||
static void term(int sig)
|
||||
{
|
||||
int ret = write(fd, &v, 1);
|
||||
|
||||
close(fd);
|
||||
fprintf(stderr, "Stopping watchdog ticks...\n");
|
||||
if (ret < 0)
|
||||
printf("\nStopping watchdog ticks failed (%d)...\n", errno);
|
||||
else
|
||||
printf("\nStopping watchdog ticks...\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -42,12 +50,14 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
int flags;
|
||||
unsigned int ping_rate = 1;
|
||||
int ret;
|
||||
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
fd = open("/dev/watchdog", O_WRONLY);
|
||||
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "Watchdog device not enabled.\n");
|
||||
fflush(stderr);
|
||||
printf("Watchdog device not enabled.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -55,36 +65,30 @@ int main(int argc, char *argv[])
|
||||
if (!strncasecmp(argv[1], "-d", 2)) {
|
||||
flags = WDIOS_DISABLECARD;
|
||||
ioctl(fd, WDIOC_SETOPTIONS, &flags);
|
||||
fprintf(stderr, "Watchdog card disabled.\n");
|
||||
fflush(stderr);
|
||||
printf("Watchdog card disabled.\n");
|
||||
goto end;
|
||||
} else if (!strncasecmp(argv[1], "-e", 2)) {
|
||||
flags = WDIOS_ENABLECARD;
|
||||
ioctl(fd, WDIOC_SETOPTIONS, &flags);
|
||||
fprintf(stderr, "Watchdog card enabled.\n");
|
||||
fflush(stderr);
|
||||
printf("Watchdog card enabled.\n");
|
||||
goto end;
|
||||
} else if (!strncasecmp(argv[1], "-t", 2) && argv[2]) {
|
||||
flags = atoi(argv[2]);
|
||||
ioctl(fd, WDIOC_SETTIMEOUT, &flags);
|
||||
fprintf(stderr, "Watchdog timeout set to %u seconds.\n", flags);
|
||||
fflush(stderr);
|
||||
printf("Watchdog timeout set to %u seconds.\n", flags);
|
||||
goto end;
|
||||
} else if (!strncasecmp(argv[1], "-p", 2) && argv[2]) {
|
||||
ping_rate = strtoul(argv[2], NULL, 0);
|
||||
fprintf(stderr, "Watchdog ping rate set to %u seconds.\n", ping_rate);
|
||||
fflush(stderr);
|
||||
printf("Watchdog ping rate set to %u seconds.\n", ping_rate);
|
||||
} else {
|
||||
fprintf(stderr, "-d to disable, -e to enable, -t <n> to set " \
|
||||
printf("-d to disable, -e to enable, -t <n> to set " \
|
||||
"the timeout,\n-p <n> to set the ping rate, and \n");
|
||||
fprintf(stderr, "run by itself to tick the card.\n");
|
||||
fflush(stderr);
|
||||
printf("run by itself to tick the card.\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Watchdog Ticking Away!\n");
|
||||
fflush(stderr);
|
||||
printf("Watchdog Ticking Away!\n");
|
||||
|
||||
signal(SIGINT, term);
|
||||
|
||||
@@ -93,6 +97,9 @@ int main(int argc, char *argv[])
|
||||
sleep(ping_rate);
|
||||
}
|
||||
end:
|
||||
ret = write(fd, &v, 1);
|
||||
if (ret < 0)
|
||||
printf("Stopping watchdog ticks failed (%d)...\n", errno);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -82,8 +82,9 @@ It contains following fields:
|
||||
* max_timeout: the watchdog timer's maximum timeout value (in seconds),
|
||||
as seen from userspace. If set, the maximum configurable value for
|
||||
'timeout'. Not used if max_hw_heartbeat_ms is non-zero.
|
||||
* min_hw_heartbeat_ms: Minimum time between heartbeats sent to the chip,
|
||||
in milli-seconds.
|
||||
* min_hw_heartbeat_ms: Hardware limit for minimum time between heartbeats,
|
||||
in milli-seconds. This value is normally 0; it should only be provided
|
||||
if the hardware can not tolerate lower intervals between heartbeats.
|
||||
* max_hw_heartbeat_ms: Maximum hardware heartbeat, in milli-seconds.
|
||||
If set, the infrastructure will send heartbeats to the watchdog driver
|
||||
if 'timeout' is larger than max_hw_heartbeat_ms, unless WDOG_ACTIVE
|
||||
@@ -166,6 +167,10 @@ they are supported. These optional routines/operations are:
|
||||
info structure).
|
||||
* status: this routine checks the status of the watchdog timer device. The
|
||||
status of the device is reported with watchdog WDIOF_* status flags/bits.
|
||||
WDIOF_MAGICCLOSE and WDIOF_KEEPALIVEPING are reported by the watchdog core;
|
||||
it is not necessary to report those bits from the driver. Also, if no status
|
||||
function is provided by the driver, the watchdog core reports the status bits
|
||||
provided in the bootstatus variable of struct watchdog_device.
|
||||
* set_timeout: this routine checks and changes the timeout of the watchdog
|
||||
timer device. It returns 0 on success, -EINVAL for "parameter out of range"
|
||||
and -EIO for "could not write value to the watchdog". On success this
|
||||
|
||||
@@ -5353,6 +5353,12 @@ T: git git://linuxtv.org/anttip/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/media/dvb-frontends/hd29l2*
|
||||
|
||||
HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER
|
||||
M: Brian Boylston <brian.boylston@hpe.com>
|
||||
S: Supported
|
||||
F: Documentation/watchdog/hpwdt.txt
|
||||
F: drivers/watchdog/hpwdt.c
|
||||
|
||||
HEWLETT-PACKARD SMART ARRAY RAID DRIVER (hpsa)
|
||||
M: Don Brace <don.brace@microsemi.com>
|
||||
L: iss_storagedev@hp.com
|
||||
|
||||
@@ -247,7 +247,8 @@
|
||||
};
|
||||
|
||||
timer@200a000 {
|
||||
compatible = "qcom,kpss-timer", "qcom,msm-timer";
|
||||
compatible = "qcom,kpss-timer",
|
||||
"qcom,kpss-wdt-apq8064", "qcom,msm-timer";
|
||||
interrupts = <1 1 0x301>,
|
||||
<1 2 0x301>,
|
||||
<1 3 0x301>;
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
};
|
||||
|
||||
watchdog@b017000 {
|
||||
compatible = "qcom,kpss-standalone";
|
||||
compatible = "qcom,kpss-wdt", "qcom,kpss-wdt-ipq4019";
|
||||
reg = <0xb017000 0x40>;
|
||||
clocks = <&sleep_clk>;
|
||||
timeout-sec = <10>;
|
||||
|
||||
@@ -122,7 +122,8 @@
|
||||
};
|
||||
|
||||
timer@200a000 {
|
||||
compatible = "qcom,kpss-timer", "qcom,msm-timer";
|
||||
compatible = "qcom,kpss-timer",
|
||||
"qcom,kpss-wdt-ipq8064", "qcom,msm-timer";
|
||||
interrupts = <1 1 0x301>,
|
||||
<1 2 0x301>,
|
||||
<1 3 0x301>,
|
||||
|
||||
@@ -87,7 +87,8 @@
|
||||
};
|
||||
|
||||
timer@200a000 {
|
||||
compatible = "qcom,kpss-timer", "qcom,msm-timer";
|
||||
compatible = "qcom,kpss-timer",
|
||||
"qcom,kpss-wdt-msm8960", "qcom,msm-timer";
|
||||
interrupts = <1 1 0x301>,
|
||||
<1 2 0x301>,
|
||||
<1 3 0x301>;
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
* platform device and to export resources for those functions.
|
||||
*/
|
||||
#define TCO_DEVICE_NAME "iTCO_wdt"
|
||||
#define SMI_EN_OFFSET 0x30
|
||||
#define SMI_EN_OFFSET 0x40
|
||||
#define SMI_EN_SIZE 4
|
||||
#define TCO_BASE_OFFSET 0x60
|
||||
#define TCO_REGS_SIZE 16
|
||||
@@ -94,6 +94,8 @@
|
||||
#define TELEM_SSRAM_SIZE 240
|
||||
#define TELEM_PMC_SSRAM_OFFSET 0x1B00
|
||||
#define TELEM_PUNIT_SSRAM_OFFSET 0x1A00
|
||||
#define TCO_PMC_OFFSET 0x8
|
||||
#define TCO_PMC_SIZE 0x4
|
||||
|
||||
static const int iTCO_version = 3;
|
||||
|
||||
@@ -502,7 +504,7 @@ static struct resource tco_res[] = {
|
||||
|
||||
static struct itco_wdt_platform_data tco_info = {
|
||||
.name = "Apollo Lake SoC",
|
||||
.version = 3,
|
||||
.version = 5,
|
||||
};
|
||||
|
||||
#define TELEMETRY_RESOURCE_PUNIT_SSRAM 0
|
||||
@@ -572,8 +574,8 @@ static int ipc_create_tco_device(void)
|
||||
res->end = res->start + SMI_EN_SIZE - 1;
|
||||
|
||||
res = tco_res + TCO_RESOURCE_GCR_MEM;
|
||||
res->start = ipcdev.gcr_base;
|
||||
res->end = res->start + ipcdev.gcr_size - 1;
|
||||
res->start = ipcdev.gcr_base + TCO_PMC_OFFSET;
|
||||
res->end = res->start + TCO_PMC_SIZE - 1;
|
||||
|
||||
ret = platform_device_add_resources(pdev, tco_res, ARRAY_SIZE(tco_res));
|
||||
if (ret) {
|
||||
|
||||
@@ -48,7 +48,6 @@ config WATCHDOG_NOWAYOUT
|
||||
|
||||
config WATCHDOG_SYSFS
|
||||
bool "Read different watchdog information through sysfs"
|
||||
default n
|
||||
help
|
||||
Say Y here if you want to enable watchdog device status read through
|
||||
sysfs attributes.
|
||||
@@ -516,6 +515,15 @@ config MAX63XX_WATCHDOG
|
||||
help
|
||||
Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
|
||||
|
||||
config MAX77620_WATCHDOG
|
||||
tristate "Maxim Max77620 Watchdog Timer"
|
||||
depends on MFD_MAX77620
|
||||
help
|
||||
This is the driver for the Max77620 watchdog timer.
|
||||
Say 'Y' here to enable the watchdog timer support for
|
||||
MAX77620 chips. To compile this driver as a module,
|
||||
choose M here: the module will be called max77620_wdt.
|
||||
|
||||
config IMX2_WDT
|
||||
tristate "IMX2+ Watchdog"
|
||||
depends on ARCH_MXC || ARCH_LAYERSCAPE
|
||||
@@ -609,6 +617,16 @@ config QCOM_WDT
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called qcom_wdt.
|
||||
|
||||
config MESON_GXBB_WATCHDOG
|
||||
tristate "Amlogic Meson GXBB SoCs watchdog support"
|
||||
depends on ARCH_MESON
|
||||
select WATCHDOG_CORE
|
||||
help
|
||||
Say Y here to include support for the watchdog timer
|
||||
in Amlogic Meson GXBB SoCs.
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called meson_gxbb_wdt.
|
||||
|
||||
config MESON_WATCHDOG
|
||||
tristate "Amlogic Meson SoCs watchdog support"
|
||||
depends on ARCH_MESON
|
||||
@@ -669,6 +687,19 @@ config RENESAS_WDT
|
||||
This driver adds watchdog support for the integrated watchdogs in the
|
||||
Renesas R-Car and other SH-Mobile SoCs (usually named RWDT or SWDT).
|
||||
|
||||
config ASPEED_WATCHDOG
|
||||
tristate "Aspeed 2400 watchdog support"
|
||||
depends on ARCH_ASPEED || COMPILE_TEST
|
||||
select WATCHDOG_CORE
|
||||
help
|
||||
Say Y here to include support for the watchdog timer
|
||||
in Apseed BMC SoCs.
|
||||
|
||||
This driver is required to reboot the SoC.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called aspeed_wdt.
|
||||
|
||||
# AVR32 Architecture
|
||||
|
||||
config AT32AP700X_WDT
|
||||
|
||||
@@ -67,6 +67,7 @@ obj-$(CONFIG_ST_LPC_WATCHDOG) += st_lpc_wdt.o
|
||||
obj-$(CONFIG_QCOM_WDT) += qcom-wdt.o
|
||||
obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o
|
||||
obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
|
||||
obj-$(CONFIG_MESON_GXBB_WATCHDOG) += meson_gxbb_wdt.o
|
||||
obj-$(CONFIG_MESON_WATCHDOG) += meson_wdt.o
|
||||
obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o
|
||||
obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o
|
||||
@@ -74,6 +75,7 @@ obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o
|
||||
obj-$(CONFIG_BCM7038_WDT) += bcm7038_wdt.o
|
||||
obj-$(CONFIG_ATLAS7_WATCHDOG) += atlas7_wdt.o
|
||||
obj-$(CONFIG_RENESAS_WDT) += renesas_wdt.o
|
||||
obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o
|
||||
|
||||
# AVR32 Architecture
|
||||
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
|
||||
@@ -203,6 +205,7 @@ obj-$(CONFIG_TANGOX_WATCHDOG) += tangox_wdt.o
|
||||
obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
|
||||
obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
|
||||
obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
|
||||
obj-$(CONFIG_MAX77620_WATCHDOG) += max77620_wdt.o
|
||||
obj-$(CONFIG_ZIIRAVE_WATCHDOG) += ziirave_wdt.o
|
||||
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
|
||||
obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright 2016 IBM Corporation
|
||||
*
|
||||
* Joel Stanley <joel@jms.id.au>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/watchdog.h>
|
||||
|
||||
struct aspeed_wdt {
|
||||
struct watchdog_device wdd;
|
||||
void __iomem *base;
|
||||
u32 ctrl;
|
||||
};
|
||||
|
||||
static const struct of_device_id aspeed_wdt_of_table[] = {
|
||||
{ .compatible = "aspeed,ast2400-wdt" },
|
||||
{ .compatible = "aspeed,ast2500-wdt" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
|
||||
|
||||
#define WDT_STATUS 0x00
|
||||
#define WDT_RELOAD_VALUE 0x04
|
||||
#define WDT_RESTART 0x08
|
||||
#define WDT_CTRL 0x0C
|
||||
#define WDT_CTRL_RESET_MODE_SOC (0x00 << 5)
|
||||
#define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5)
|
||||
#define WDT_CTRL_1MHZ_CLK BIT(4)
|
||||
#define WDT_CTRL_WDT_EXT BIT(3)
|
||||
#define WDT_CTRL_WDT_INTR BIT(2)
|
||||
#define WDT_CTRL_RESET_SYSTEM BIT(1)
|
||||
#define WDT_CTRL_ENABLE BIT(0)
|
||||
|
||||
#define WDT_RESTART_MAGIC 0x4755
|
||||
|
||||
/* 32 bits at 1MHz, in milliseconds */
|
||||
#define WDT_MAX_TIMEOUT_MS 4294967
|
||||
#define WDT_DEFAULT_TIMEOUT 30
|
||||
#define WDT_RATE_1MHZ 1000000
|
||||
|
||||
static struct aspeed_wdt *to_aspeed_wdt(struct watchdog_device *wdd)
|
||||
{
|
||||
return container_of(wdd, struct aspeed_wdt, wdd);
|
||||
}
|
||||
|
||||
static void aspeed_wdt_enable(struct aspeed_wdt *wdt, int count)
|
||||
{
|
||||
wdt->ctrl |= WDT_CTRL_ENABLE;
|
||||
|
||||
writel(0, wdt->base + WDT_CTRL);
|
||||
writel(count, wdt->base + WDT_RELOAD_VALUE);
|
||||
writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART);
|
||||
writel(wdt->ctrl, wdt->base + WDT_CTRL);
|
||||
}
|
||||
|
||||
static int aspeed_wdt_start(struct watchdog_device *wdd)
|
||||
{
|
||||
struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
|
||||
|
||||
aspeed_wdt_enable(wdt, wdd->timeout * WDT_RATE_1MHZ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aspeed_wdt_stop(struct watchdog_device *wdd)
|
||||
{
|
||||
struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
|
||||
|
||||
wdt->ctrl &= ~WDT_CTRL_ENABLE;
|
||||
writel(wdt->ctrl, wdt->base + WDT_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aspeed_wdt_ping(struct watchdog_device *wdd)
|
||||
{
|
||||
struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
|
||||
|
||||
writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aspeed_wdt_set_timeout(struct watchdog_device *wdd,
|
||||
unsigned int timeout)
|
||||
{
|
||||
struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
|
||||
u32 actual;
|
||||
|
||||
wdd->timeout = timeout;
|
||||
|
||||
actual = min(timeout, wdd->max_hw_heartbeat_ms * 1000);
|
||||
|
||||
writel(actual * WDT_RATE_1MHZ, wdt->base + WDT_RELOAD_VALUE);
|
||||
writel(WDT_RESTART_MAGIC, wdt->base + WDT_RESTART);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aspeed_wdt_restart(struct watchdog_device *wdd,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct aspeed_wdt *wdt = to_aspeed_wdt(wdd);
|
||||
|
||||
aspeed_wdt_enable(wdt, 128 * WDT_RATE_1MHZ / 1000);
|
||||
|
||||
mdelay(1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct watchdog_ops aspeed_wdt_ops = {
|
||||
.start = aspeed_wdt_start,
|
||||
.stop = aspeed_wdt_stop,
|
||||
.ping = aspeed_wdt_ping,
|
||||
.set_timeout = aspeed_wdt_set_timeout,
|
||||
.restart = aspeed_wdt_restart,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct watchdog_info aspeed_wdt_info = {
|
||||
.options = WDIOF_KEEPALIVEPING
|
||||
| WDIOF_MAGICCLOSE
|
||||
| WDIOF_SETTIMEOUT,
|
||||
.identity = KBUILD_MODNAME,
|
||||
};
|
||||
|
||||
static int aspeed_wdt_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct aspeed_wdt *wdt = platform_get_drvdata(pdev);
|
||||
|
||||
watchdog_unregister_device(&wdt->wdd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aspeed_wdt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct aspeed_wdt *wdt;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
|
||||
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
|
||||
if (!wdt)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
wdt->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(wdt->base))
|
||||
return PTR_ERR(wdt->base);
|
||||
|
||||
/*
|
||||
* The ast2400 wdt can run at PCLK, or 1MHz. The ast2500 only
|
||||
* runs at 1MHz. We chose to always run at 1MHz, as there's no
|
||||
* good reason to have a faster watchdog counter.
|
||||
*/
|
||||
wdt->wdd.info = &aspeed_wdt_info;
|
||||
wdt->wdd.ops = &aspeed_wdt_ops;
|
||||
wdt->wdd.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT_MS;
|
||||
wdt->wdd.parent = &pdev->dev;
|
||||
|
||||
wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT;
|
||||
watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
|
||||
|
||||
/*
|
||||
* Control reset on a per-device basis to ensure the
|
||||
* host is not affected by a BMC reboot, so only reset
|
||||
* the SOC and not the full chip
|
||||
*/
|
||||
wdt->ctrl = WDT_CTRL_RESET_MODE_SOC |
|
||||
WDT_CTRL_1MHZ_CLK |
|
||||
WDT_CTRL_RESET_SYSTEM;
|
||||
|
||||
if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) {
|
||||
aspeed_wdt_start(&wdt->wdd);
|
||||
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
|
||||
}
|
||||
|
||||
ret = watchdog_register_device(&wdt->wdd);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, wdt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver aspeed_watchdog_driver = {
|
||||
.probe = aspeed_wdt_probe,
|
||||
.remove = aspeed_wdt_remove,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.of_match_table = of_match_ptr(aspeed_wdt_of_table),
|
||||
},
|
||||
};
|
||||
module_platform_driver(aspeed_watchdog_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Aspeed Watchdog Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -82,12 +82,6 @@ static int bcm2835_wdt_stop(struct watchdog_device *wdog)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcm2835_wdt_set_timeout(struct watchdog_device *wdog, unsigned int t)
|
||||
{
|
||||
wdog->timeout = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int bcm2835_wdt_get_timeleft(struct watchdog_device *wdog)
|
||||
{
|
||||
struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
|
||||
@@ -96,15 +90,14 @@ static unsigned int bcm2835_wdt_get_timeleft(struct watchdog_device *wdog)
|
||||
return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET);
|
||||
}
|
||||
|
||||
static struct watchdog_ops bcm2835_wdt_ops = {
|
||||
static const struct watchdog_ops bcm2835_wdt_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.start = bcm2835_wdt_start,
|
||||
.stop = bcm2835_wdt_stop,
|
||||
.set_timeout = bcm2835_wdt_set_timeout,
|
||||
.get_timeleft = bcm2835_wdt_get_timeleft,
|
||||
};
|
||||
|
||||
static struct watchdog_info bcm2835_wdt_info = {
|
||||
static const struct watchdog_info bcm2835_wdt_info = {
|
||||
.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
|
||||
WDIOF_KEEPALIVEPING,
|
||||
.identity = "Broadcom BCM2835 Watchdog timer",
|
||||
|
||||
@@ -34,6 +34,7 @@ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
|
||||
#define DA9063_WDT_MIN_TIMEOUT wdt_timeout[DA9063_TWDSCALE_MIN]
|
||||
#define DA9063_WDT_MAX_TIMEOUT wdt_timeout[DA9063_TWDSCALE_MAX]
|
||||
#define DA9063_WDG_TIMEOUT wdt_timeout[3]
|
||||
#define DA9063_RESET_PROTECTION_MS 256
|
||||
|
||||
struct da9063_watchdog {
|
||||
struct da9063 *da9063;
|
||||
@@ -171,6 +172,7 @@ static int da9063_wdt_probe(struct platform_device *pdev)
|
||||
wdt->wdtdev.ops = &da9063_watchdog_ops;
|
||||
wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT;
|
||||
wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT;
|
||||
wdt->wdtdev.min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS;
|
||||
wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT;
|
||||
wdt->wdtdev.parent = &pdev->dev;
|
||||
|
||||
|
||||
@@ -45,9 +45,11 @@
|
||||
#define SIO_REG_DEVREV 0x22 /* Device revision */
|
||||
#define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
|
||||
#define SIO_REG_ROM_ADDR_SEL 0x27 /* ROM address select */
|
||||
#define SIO_F81866_REG_PORT_SEL 0x27 /* F81866 Multi-Function Register */
|
||||
#define SIO_REG_MFUNCT1 0x29 /* Multi function select 1 */
|
||||
#define SIO_REG_MFUNCT2 0x2a /* Multi function select 2 */
|
||||
#define SIO_REG_MFUNCT3 0x2b /* Multi function select 3 */
|
||||
#define SIO_F81866_REG_GPIO1 0x2c /* F81866 GPIO1 Enable Register */
|
||||
#define SIO_REG_ENABLE 0x30 /* Logical device enable */
|
||||
#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
|
||||
|
||||
@@ -60,6 +62,7 @@
|
||||
#define SIO_F71882_ID 0x0541 /* Chipset ID */
|
||||
#define SIO_F71889_ID 0x0723 /* Chipset ID */
|
||||
#define SIO_F81865_ID 0x0704 /* Chipset ID */
|
||||
#define SIO_F81866_ID 0x1010 /* Chipset ID */
|
||||
|
||||
#define F71808FG_REG_WDO_CONF 0xf0
|
||||
#define F71808FG_REG_WDT_CONF 0xf5
|
||||
@@ -116,7 +119,8 @@ 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, f71869, f71882fg, f71889fg, f81865 };
|
||||
enum chips { f71808fg, f71858fg, f71862fg, f71869, f71882fg, f71889fg, f81865,
|
||||
f81866};
|
||||
|
||||
static const char *f71808e_names[] = {
|
||||
"f71808fg",
|
||||
@@ -126,6 +130,7 @@ static const char *f71808e_names[] = {
|
||||
"f71882fg",
|
||||
"f71889fg",
|
||||
"f81865",
|
||||
"f81866",
|
||||
};
|
||||
|
||||
/* Super-I/O Function prototypes */
|
||||
@@ -370,6 +375,22 @@ static int watchdog_start(void)
|
||||
superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 5);
|
||||
break;
|
||||
|
||||
case f81866:
|
||||
/* Set pin 70 to WDTRST# */
|
||||
superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL,
|
||||
BIT(3) | BIT(0));
|
||||
superio_set_bit(watchdog.sioaddr, SIO_F81866_REG_PORT_SEL,
|
||||
BIT(2));
|
||||
/*
|
||||
* GPIO1 Control Register when 27h BIT3:2 = 01 & BIT0 = 0.
|
||||
* The PIN 70(GPIO15/WDTRST) is controlled by 2Ch:
|
||||
* BIT5: 0 -> WDTRST#
|
||||
* 1 -> GPIO15
|
||||
*/
|
||||
superio_clear_bit(watchdog.sioaddr, SIO_F81866_REG_GPIO1,
|
||||
BIT(5));
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* 'default' label to shut up the compiler and catch
|
||||
@@ -382,7 +403,7 @@ static int watchdog_start(void)
|
||||
superio_select(watchdog.sioaddr, SIO_F71808FG_LD_WDT);
|
||||
superio_set_bit(watchdog.sioaddr, SIO_REG_ENABLE, 0);
|
||||
|
||||
if (watchdog.type == f81865)
|
||||
if (watchdog.type == f81865 || watchdog.type == f81866)
|
||||
superio_set_bit(watchdog.sioaddr, F81865_REG_WDO_CONF,
|
||||
F81865_FLAG_WDOUT_EN);
|
||||
else
|
||||
@@ -788,6 +809,9 @@ static int __init f71808e_find(int sioaddr)
|
||||
case SIO_F81865_ID:
|
||||
watchdog.type = f81865;
|
||||
break;
|
||||
case SIO_F81866_ID:
|
||||
watchdog.type = f81866;
|
||||
break;
|
||||
default:
|
||||
pr_info("Unrecognized Fintek device: %04x\n",
|
||||
(unsigned int)devid);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user