Merge git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck: - add support for the watchdog on Meson8 and Meson8m2 - add support for MediaTek MT7623 and MT7622 SoC - add support for the r8a77995 wdt - explicitly request exclusive reset control for asm9260_wdt, zx2967_wdt, rt2880_wdt and mt7621_wdt - improvements to asm9260_wdt, aspeed_wdt, renesas_wdt and cadence_wdt - add support for reading freq via CCF + suspend/resume support for of_xilinx_wdt - constify watchdog_ops and various device-id structures - revert of commit 1fccb73011ea ("iTCO_wdt: all versions count down twice") (Bug 196509) * git://www.linux-watchdog.org/linux-watchdog: (40 commits) watchdog: mei_wdt: constify mei_cl_device_id watchdog: sp805: constify amba_id watchdog: ziirave: constify i2c_device_id watchdog: sc1200: constify pnp_device_id dt-bindings: watchdog: renesas-wdt: Add support for the r8a77995 wdt watchdog: renesas_wdt: update copyright dates watchdog: renesas_wdt: make 'clk' a variable local to probe() watchdog: renesas_wdt: consistently use RuntimePM for clock management watchdog: aspeed: Support configuration of external signal properties dt-bindings: watchdog: aspeed: External reset signal properties drivers/watchdog: Add optional ASPEED device tree properties drivers/watchdog: ASPEED reference dev tree properties for config watchdog: da9063_wdt: Simplify by removing unneeded struct... watchdog: bcm7038: Check the return value from clk_prepare_enable() watchdog: qcom: Check for platform_get_resource() failure watchdog: of_xilinx_wdt: Add suspend/resume support watchdog: of_xilinx_wdt: Add support for reading freq via CCF dt-bindings: watchdog: mediatek: add support for MediaTek MT7623 and MT7622 SoC watchdog: max77620_wdt: constify platform_device_id watchdog: pcwd_usb: constify usb_device_id ...
This commit is contained in:
commit
939ae58960
@ -8,9 +8,49 @@ Required properties:
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region
|
||||
|
||||
Optional properties:
|
||||
|
||||
- aspeed,reset-type = "cpu|soc|system|none"
|
||||
|
||||
Reset behavior - Whenever a timeout occurs the watchdog can be programmed
|
||||
to generate one of three different, mutually exclusive, types of resets.
|
||||
|
||||
Type "none" can be specified to indicate that no resets are to be done.
|
||||
This is useful in situations where another watchdog engine on chip is
|
||||
to perform the reset.
|
||||
|
||||
If 'aspeed,reset-type=' is not specfied the default is to enable system
|
||||
reset.
|
||||
|
||||
Reset types:
|
||||
|
||||
- cpu: Reset CPU on watchdog timeout
|
||||
|
||||
- soc: Reset 'System on Chip' on watchdog timeout
|
||||
|
||||
- system: Reset system on watchdog timeout
|
||||
|
||||
- none: No reset is performed on timeout. Assumes another watchdog
|
||||
engine is responsible for this.
|
||||
|
||||
- aspeed,alt-boot: If property is present then boot from alternate block.
|
||||
- aspeed,external-signal: If property is present then signal is sent to
|
||||
external reset counter (only WDT1 and WDT2). If not
|
||||
specified no external signal is sent.
|
||||
- aspeed,ext-pulse-duration: External signal pulse duration in microseconds
|
||||
|
||||
Optional properties for AST2500-compatible watchdogs:
|
||||
- aspeed,ext-push-pull: If aspeed,external-signal is present, set the pin's
|
||||
drive type to push-pull. The default is open-drain.
|
||||
- aspeed,ext-active-high: If aspeed,external-signal is present and and the pin
|
||||
is configured as push-pull, then set the pulse
|
||||
polarity to active-high. The default is active-low.
|
||||
|
||||
Example:
|
||||
|
||||
wdt1: watchdog@1e785000 {
|
||||
compatible = "aspeed,ast2400-wdt";
|
||||
reg = <0x1e785000 0x1c>;
|
||||
aspeed,reset-type = "system";
|
||||
aspeed,external-signal;
|
||||
};
|
||||
|
@ -2,7 +2,11 @@ Meson SoCs Watchdog timer
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "amlogic,meson6-wdt" or "amlogic,meson8b-wdt"
|
||||
- compatible : depending on the SoC this should be one of:
|
||||
"amlogic,meson6-wdt" on Meson6 SoCs
|
||||
"amlogic,meson8-wdt" and "amlogic,meson6-wdt" on Meson8 SoCs
|
||||
"amlogic,meson8b-wdt" on Meson8b SoCs
|
||||
"amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
|
||||
Example:
|
||||
|
@ -6,6 +6,8 @@ Required properties:
|
||||
"mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701
|
||||
"mediatek,mt6589-wdt": for MT6589
|
||||
"mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797
|
||||
"mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
|
||||
"mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
|
||||
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
|
||||
|
@ -6,6 +6,7 @@ Required properties:
|
||||
Examples with soctypes are:
|
||||
- "renesas,r8a7795-wdt" (R-Car H3)
|
||||
- "renesas,r8a7796-wdt" (R-Car M3-W)
|
||||
- "renesas,r8a77995-wdt" (R-Car D3)
|
||||
- "renesas,r7s72100-wdt" (RZ/A1)
|
||||
|
||||
When compatible with the generic version, nodes must list the SoC-specific
|
||||
|
@ -117,7 +117,7 @@ nowayout: Watchdog cannot be stopped once started
|
||||
-------------------------------------------------
|
||||
iTCO_wdt:
|
||||
heartbeat: Watchdog heartbeat in seconds.
|
||||
(5<=heartbeat<=74 (TCO v1) or 1226 (TCO v2), default=30)
|
||||
(2<heartbeat<39 (TCO v1) or 613 (TCO v2), default=30)
|
||||
nowayout: Watchdog cannot be stopped once started
|
||||
(default=kernel config parameter)
|
||||
-------------------------------------------------
|
||||
|
@ -82,7 +82,7 @@ static unsigned int asm9260_wdt_gettimeleft(struct watchdog_device *wdd)
|
||||
|
||||
counter = ioread32(priv->iobase + HW_WDTV);
|
||||
|
||||
return DIV_ROUND_CLOSEST(counter, priv->wdt_freq);
|
||||
return counter / priv->wdt_freq;
|
||||
}
|
||||
|
||||
static int asm9260_wdt_updatetimeout(struct watchdog_device *wdd)
|
||||
@ -296,7 +296,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->rst = devm_reset_control_get(&pdev->dev, "wdt_rst");
|
||||
priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst");
|
||||
if (IS_ERR(priv->rst))
|
||||
return PTR_ERR(priv->rst);
|
||||
|
||||
|
@ -23,9 +23,21 @@ struct aspeed_wdt {
|
||||
u32 ctrl;
|
||||
};
|
||||
|
||||
struct aspeed_wdt_config {
|
||||
u32 ext_pulse_width_mask;
|
||||
};
|
||||
|
||||
static const struct aspeed_wdt_config ast2400_config = {
|
||||
.ext_pulse_width_mask = 0xff,
|
||||
};
|
||||
|
||||
static const struct aspeed_wdt_config ast2500_config = {
|
||||
.ext_pulse_width_mask = 0xfffff,
|
||||
};
|
||||
|
||||
static const struct of_device_id aspeed_wdt_of_table[] = {
|
||||
{ .compatible = "aspeed,ast2400-wdt" },
|
||||
{ .compatible = "aspeed,ast2500-wdt" },
|
||||
{ .compatible = "aspeed,ast2400-wdt", .data = &ast2400_config },
|
||||
{ .compatible = "aspeed,ast2500-wdt", .data = &ast2500_config },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
|
||||
@ -36,12 +48,45 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
|
||||
#define WDT_CTRL 0x0C
|
||||
#define WDT_CTRL_RESET_MODE_SOC (0x00 << 5)
|
||||
#define WDT_CTRL_RESET_MODE_FULL_CHIP (0x01 << 5)
|
||||
#define WDT_CTRL_RESET_MODE_ARM_CPU (0x10 << 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)
|
||||
|
||||
/*
|
||||
* WDT_RESET_WIDTH controls the characteristics of the external pulse (if
|
||||
* enabled), specifically:
|
||||
*
|
||||
* * Pulse duration
|
||||
* * Drive mode: push-pull vs open-drain
|
||||
* * Polarity: Active high or active low
|
||||
*
|
||||
* Pulse duration configuration is available on both the AST2400 and AST2500,
|
||||
* though the field changes between SoCs:
|
||||
*
|
||||
* AST2400: Bits 7:0
|
||||
* AST2500: Bits 19:0
|
||||
*
|
||||
* This difference is captured in struct aspeed_wdt_config.
|
||||
*
|
||||
* The AST2500 exposes the drive mode and polarity options, but not in a
|
||||
* regular fashion. For read purposes, bit 31 represents active high or low,
|
||||
* and bit 30 represents push-pull or open-drain. With respect to write, magic
|
||||
* values need to be written to the top byte to change the state of the drive
|
||||
* mode and polarity bits. Any other value written to the top byte has no
|
||||
* effect on the state of the drive mode or polarity bits. However, the pulse
|
||||
* width value must be preserved (as desired) if written.
|
||||
*/
|
||||
#define WDT_RESET_WIDTH 0x18
|
||||
#define WDT_RESET_WIDTH_ACTIVE_HIGH BIT(31)
|
||||
#define WDT_ACTIVE_HIGH_MAGIC (0xA5 << 24)
|
||||
#define WDT_ACTIVE_LOW_MAGIC (0x5A << 24)
|
||||
#define WDT_RESET_WIDTH_PUSH_PULL BIT(30)
|
||||
#define WDT_PUSH_PULL_MAGIC (0xA8 << 24)
|
||||
#define WDT_OPEN_DRAIN_MAGIC (0x8A << 24)
|
||||
|
||||
#define WDT_RESTART_MAGIC 0x4755
|
||||
|
||||
/* 32 bits at 1MHz, in milliseconds */
|
||||
@ -138,8 +183,13 @@ static const struct watchdog_info aspeed_wdt_info = {
|
||||
|
||||
static int aspeed_wdt_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct aspeed_wdt_config *config;
|
||||
const struct of_device_id *ofdid;
|
||||
struct aspeed_wdt *wdt;
|
||||
struct resource *res;
|
||||
struct device_node *np;
|
||||
const char *reset_type;
|
||||
u32 duration;
|
||||
int ret;
|
||||
|
||||
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
|
||||
@ -164,20 +214,88 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
|
||||
wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT;
|
||||
watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
|
||||
|
||||
np = pdev->dev.of_node;
|
||||
|
||||
ofdid = of_match_node(aspeed_wdt_of_table, np);
|
||||
if (!ofdid)
|
||||
return -EINVAL;
|
||||
config = ofdid->data;
|
||||
|
||||
wdt->ctrl = WDT_CTRL_1MHZ_CLK;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* host is not affected by a BMC reboot
|
||||
*/
|
||||
wdt->ctrl = WDT_CTRL_RESET_MODE_SOC |
|
||||
WDT_CTRL_1MHZ_CLK |
|
||||
WDT_CTRL_RESET_SYSTEM;
|
||||
ret = of_property_read_string(np, "aspeed,reset-type", &reset_type);
|
||||
if (ret) {
|
||||
wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC | WDT_CTRL_RESET_SYSTEM;
|
||||
} else {
|
||||
if (!strcmp(reset_type, "cpu"))
|
||||
wdt->ctrl |= WDT_CTRL_RESET_MODE_ARM_CPU;
|
||||
else if (!strcmp(reset_type, "soc"))
|
||||
wdt->ctrl |= WDT_CTRL_RESET_MODE_SOC;
|
||||
else if (!strcmp(reset_type, "system"))
|
||||
wdt->ctrl |= WDT_CTRL_RESET_SYSTEM;
|
||||
else if (strcmp(reset_type, "none"))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (of_property_read_bool(np, "aspeed,external-signal"))
|
||||
wdt->ctrl |= WDT_CTRL_WDT_EXT;
|
||||
|
||||
writel(wdt->ctrl, wdt->base + WDT_CTRL);
|
||||
|
||||
if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) {
|
||||
aspeed_wdt_start(&wdt->wdd);
|
||||
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
|
||||
}
|
||||
|
||||
if (of_device_is_compatible(np, "aspeed,ast2500-wdt")) {
|
||||
u32 reg = readl(wdt->base + WDT_RESET_WIDTH);
|
||||
|
||||
reg &= config->ext_pulse_width_mask;
|
||||
if (of_property_read_bool(np, "aspeed,ext-push-pull"))
|
||||
reg |= WDT_PUSH_PULL_MAGIC;
|
||||
else
|
||||
reg |= WDT_OPEN_DRAIN_MAGIC;
|
||||
|
||||
writel(reg, wdt->base + WDT_RESET_WIDTH);
|
||||
|
||||
reg &= config->ext_pulse_width_mask;
|
||||
if (of_property_read_bool(np, "aspeed,ext-active-high"))
|
||||
reg |= WDT_ACTIVE_HIGH_MAGIC;
|
||||
else
|
||||
reg |= WDT_ACTIVE_LOW_MAGIC;
|
||||
|
||||
writel(reg, wdt->base + WDT_RESET_WIDTH);
|
||||
}
|
||||
|
||||
if (!of_property_read_u32(np, "aspeed,ext-pulse-duration", &duration)) {
|
||||
u32 max_duration = config->ext_pulse_width_mask + 1;
|
||||
|
||||
if (duration == 0 || duration > max_duration) {
|
||||
dev_err(&pdev->dev, "Invalid pulse duration: %uus\n",
|
||||
duration);
|
||||
duration = max(1U, min(max_duration, duration));
|
||||
dev_info(&pdev->dev, "Pulse duration set to %uus\n",
|
||||
duration);
|
||||
}
|
||||
|
||||
/*
|
||||
* The watchdog is always configured with a 1MHz source, so
|
||||
* there is no need to scale the microsecond value. However we
|
||||
* need to offset it - from the datasheet:
|
||||
*
|
||||
* "This register decides the asserting duration of wdt_ext and
|
||||
* wdt_rstarm signal. The default value is 0xFF. It means the
|
||||
* default asserting duration of wdt_ext and wdt_rstarm is
|
||||
* 256us."
|
||||
*
|
||||
* This implies a value of 0 gives a 1us pulse.
|
||||
*/
|
||||
writel(duration - 1, wdt->base + WDT_RESET_WIDTH);
|
||||
}
|
||||
|
||||
ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register\n");
|
||||
|
@ -136,7 +136,9 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
|
||||
wdt->clk = devm_clk_get(dev, NULL);
|
||||
/* If unable to get clock, use default frequency */
|
||||
if (!IS_ERR(wdt->clk)) {
|
||||
clk_prepare_enable(wdt->clk);
|
||||
err = clk_prepare_enable(wdt->clk);
|
||||
if (err)
|
||||
return err;
|
||||
wdt->rate = clk_get_rate(wdt->clk);
|
||||
/* Prevent divide-by-zero exception */
|
||||
if (!wdt->rate)
|
||||
|
@ -52,12 +52,12 @@
|
||||
static int wdt_timeout;
|
||||
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||
|
||||
module_param(wdt_timeout, int, 0);
|
||||
module_param(wdt_timeout, int, 0644);
|
||||
MODULE_PARM_DESC(wdt_timeout,
|
||||
"Watchdog time in seconds. (default="
|
||||
__MODULE_STRING(CDNS_WDT_DEFAULT_TIMEOUT) ")");
|
||||
|
||||
module_param(nowayout, int, 0);
|
||||
module_param(nowayout, int, 0644);
|
||||
MODULE_PARM_DESC(nowayout,
|
||||
"Watchdog cannot be stopped once started (default="
|
||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
||||
@ -368,7 +368,7 @@ static int cdns_wdt_probe(struct platform_device *pdev)
|
||||
}
|
||||
platform_set_drvdata(pdev, wdt);
|
||||
|
||||
dev_dbg(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
|
||||
dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
|
||||
wdt->regs, cdns_wdt_device->timeout,
|
||||
nowayout ? ", nowayout" : "");
|
||||
|
||||
|
@ -218,7 +218,7 @@ static const struct watchdog_info coh901327_ident = {
|
||||
.identity = DRV_NAME,
|
||||
};
|
||||
|
||||
static struct watchdog_ops coh901327_ops = {
|
||||
static const struct watchdog_ops coh901327_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.start = coh901327_start,
|
||||
.stop = coh901327_stop,
|
||||
|
@ -36,11 +36,6 @@ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
|
||||
#define DA9063_WDG_TIMEOUT wdt_timeout[3]
|
||||
#define DA9063_RESET_PROTECTION_MS 256
|
||||
|
||||
struct da9063_watchdog {
|
||||
struct da9063 *da9063;
|
||||
struct watchdog_device wdtdev;
|
||||
};
|
||||
|
||||
static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -61,14 +56,14 @@ static int _da9063_wdt_set_timeout(struct da9063 *da9063, unsigned int regval)
|
||||
|
||||
static int da9063_wdt_start(struct watchdog_device *wdd)
|
||||
{
|
||||
struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd);
|
||||
struct da9063 *da9063 = watchdog_get_drvdata(wdd);
|
||||
unsigned int selector;
|
||||
int ret;
|
||||
|
||||
selector = da9063_wdt_timeout_to_sel(wdt->wdtdev.timeout);
|
||||
ret = _da9063_wdt_set_timeout(wdt->da9063, selector);
|
||||
selector = da9063_wdt_timeout_to_sel(wdd->timeout);
|
||||
ret = _da9063_wdt_set_timeout(da9063, selector);
|
||||
if (ret)
|
||||
dev_err(wdt->da9063->dev, "Watchdog failed to start (err = %d)\n",
|
||||
dev_err(da9063->dev, "Watchdog failed to start (err = %d)\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
@ -76,13 +71,13 @@ static int da9063_wdt_start(struct watchdog_device *wdd)
|
||||
|
||||
static int da9063_wdt_stop(struct watchdog_device *wdd)
|
||||
{
|
||||
struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd);
|
||||
struct da9063 *da9063 = watchdog_get_drvdata(wdd);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(wdt->da9063->regmap, DA9063_REG_CONTROL_D,
|
||||
ret = regmap_update_bits(da9063->regmap, DA9063_REG_CONTROL_D,
|
||||
DA9063_TWDSCALE_MASK, DA9063_TWDSCALE_DISABLE);
|
||||
if (ret)
|
||||
dev_alert(wdt->da9063->dev, "Watchdog failed to stop (err = %d)\n",
|
||||
dev_alert(da9063->dev, "Watchdog failed to stop (err = %d)\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
@ -90,13 +85,13 @@ static int da9063_wdt_stop(struct watchdog_device *wdd)
|
||||
|
||||
static int da9063_wdt_ping(struct watchdog_device *wdd)
|
||||
{
|
||||
struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd);
|
||||
struct da9063 *da9063 = watchdog_get_drvdata(wdd);
|
||||
int ret;
|
||||
|
||||
ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F,
|
||||
ret = regmap_write(da9063->regmap, DA9063_REG_CONTROL_F,
|
||||
DA9063_WATCHDOG);
|
||||
if (ret)
|
||||
dev_alert(wdt->da9063->dev, "Failed to ping the watchdog (err = %d)\n",
|
||||
dev_alert(da9063->dev, "Failed to ping the watchdog (err = %d)\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
@ -105,14 +100,14 @@ static int da9063_wdt_ping(struct watchdog_device *wdd)
|
||||
static int da9063_wdt_set_timeout(struct watchdog_device *wdd,
|
||||
unsigned int timeout)
|
||||
{
|
||||
struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd);
|
||||
struct da9063 *da9063 = watchdog_get_drvdata(wdd);
|
||||
unsigned int selector;
|
||||
int ret;
|
||||
|
||||
selector = da9063_wdt_timeout_to_sel(timeout);
|
||||
ret = _da9063_wdt_set_timeout(wdt->da9063, selector);
|
||||
ret = _da9063_wdt_set_timeout(da9063, selector);
|
||||
if (ret)
|
||||
dev_err(wdt->da9063->dev, "Failed to set watchdog timeout (err = %d)\n",
|
||||
dev_err(da9063->dev, "Failed to set watchdog timeout (err = %d)\n",
|
||||
ret);
|
||||
else
|
||||
wdd->timeout = wdt_timeout[selector];
|
||||
@ -123,13 +118,13 @@ static int da9063_wdt_set_timeout(struct watchdog_device *wdd,
|
||||
static int da9063_wdt_restart(struct watchdog_device *wdd, unsigned long action,
|
||||
void *data)
|
||||
{
|
||||
struct da9063_watchdog *wdt = watchdog_get_drvdata(wdd);
|
||||
struct da9063 *da9063 = watchdog_get_drvdata(wdd);
|
||||
int ret;
|
||||
|
||||
ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F,
|
||||
ret = regmap_write(da9063->regmap, DA9063_REG_CONTROL_F,
|
||||
DA9063_SHUTDOWN);
|
||||
if (ret)
|
||||
dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n",
|
||||
dev_alert(da9063->dev, "Failed to shutdown (err = %d)\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
@ -152,7 +147,7 @@ static const struct watchdog_ops da9063_watchdog_ops = {
|
||||
static int da9063_wdt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct da9063 *da9063;
|
||||
struct da9063_watchdog *wdt;
|
||||
struct watchdog_device *wdd;
|
||||
|
||||
if (!pdev->dev.parent)
|
||||
return -EINVAL;
|
||||
@ -161,27 +156,25 @@ static int da9063_wdt_probe(struct platform_device *pdev)
|
||||
if (!da9063)
|
||||
return -EINVAL;
|
||||
|
||||
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
|
||||
if (!wdt)
|
||||
wdd = devm_kzalloc(&pdev->dev, sizeof(*wdd), GFP_KERNEL);
|
||||
if (!wdd)
|
||||
return -ENOMEM;
|
||||
|
||||
wdt->da9063 = da9063;
|
||||
wdd->info = &da9063_watchdog_info;
|
||||
wdd->ops = &da9063_watchdog_ops;
|
||||
wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT;
|
||||
wdd->max_timeout = DA9063_WDT_MAX_TIMEOUT;
|
||||
wdd->min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS;
|
||||
wdd->timeout = DA9063_WDG_TIMEOUT;
|
||||
wdd->parent = &pdev->dev;
|
||||
|
||||
wdt->wdtdev.info = &da9063_watchdog_info;
|
||||
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;
|
||||
wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS;
|
||||
|
||||
wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
|
||||
watchdog_set_restart_priority(wdd, 128);
|
||||
|
||||
watchdog_set_restart_priority(&wdt->wdtdev, 128);
|
||||
watchdog_set_drvdata(wdd, da9063);
|
||||
|
||||
watchdog_set_drvdata(&wdt->wdtdev, wdt);
|
||||
|
||||
return devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev);
|
||||
return devm_watchdog_register_device(&pdev->dev, wdd);
|
||||
}
|
||||
|
||||
static struct platform_driver da9063_wdt_driver = {
|
||||
|
@ -213,7 +213,7 @@ static const struct watchdog_ops wdt_ops = {
|
||||
.set_timeout = wdt_set_timeout,
|
||||
};
|
||||
|
||||
static struct watchdog_info wdt_info = {
|
||||
static const struct watchdog_info wdt_info = {
|
||||
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
|
||||
.firmware_version = 0,
|
||||
.identity = "z Watchdog",
|
||||
|
@ -306,15 +306,16 @@ static int iTCO_wdt_ping(struct watchdog_device *wd_dev)
|
||||
|
||||
iTCO_vendor_pre_keepalive(p->smi_res, wd_dev->timeout);
|
||||
|
||||
/* Reset the timeout status bit so that the timer
|
||||
* needs to count down twice again before rebooting */
|
||||
outw(0x0008, TCO1_STS(p)); /* write 1 to clear bit */
|
||||
|
||||
/* Reload the timer by writing to the TCO Timer Counter register */
|
||||
if (p->iTCO_version >= 2)
|
||||
if (p->iTCO_version >= 2) {
|
||||
outw(0x01, TCO_RLD(p));
|
||||
else if (p->iTCO_version == 1)
|
||||
} else if (p->iTCO_version == 1) {
|
||||
/* Reset the timeout status bit so that the timer
|
||||
* needs to count down twice again before rebooting */
|
||||
outw(0x0008, TCO1_STS(p)); /* write 1 to clear bit */
|
||||
|
||||
outb(0x01, TCO_RLD(p));
|
||||
}
|
||||
|
||||
spin_unlock(&p->io_lock);
|
||||
return 0;
|
||||
@ -327,8 +328,11 @@ static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t)
|
||||
unsigned char val8;
|
||||
unsigned int tmrval;
|
||||
|
||||
/* The timer counts down twice before rebooting */
|
||||
tmrval = seconds_to_ticks(p, t) / 2;
|
||||
tmrval = seconds_to_ticks(p, t);
|
||||
|
||||
/* For TCO v1 the timer counts down twice before rebooting */
|
||||
if (p->iTCO_version == 1)
|
||||
tmrval /= 2;
|
||||
|
||||
/* from the specs: */
|
||||
/* "Values of 0h-3h are ignored and should not be attempted" */
|
||||
@ -381,8 +385,6 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
|
||||
spin_lock(&p->io_lock);
|
||||
val16 = inw(TCO_RLD(p));
|
||||
val16 &= 0x3ff;
|
||||
if (!(inw(TCO1_STS(p)) & 0x0008))
|
||||
val16 += (inw(TCOv2_TMR(p)) & 0x3ff);
|
||||
spin_unlock(&p->io_lock);
|
||||
|
||||
time_left = ticks_to_seconds(p, val16);
|
||||
|
@ -253,7 +253,7 @@ static const struct watchdog_info ident = {
|
||||
.identity = WATCHDOG_NAME,
|
||||
};
|
||||
|
||||
static struct watchdog_ops wdt_ops = {
|
||||
static const struct watchdog_ops wdt_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.start = wdt_start,
|
||||
.stop = wdt_stop,
|
||||
|
@ -201,7 +201,7 @@ static int max77620_wdt_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_device_id max77620_wdt_devtype[] = {
|
||||
static const struct platform_device_id max77620_wdt_devtype[] = {
|
||||
{ .name = "max77620-watchdog", },
|
||||
{ },
|
||||
};
|
||||
|
@ -670,7 +670,7 @@ static int mei_wdt_remove(struct mei_cl_device *cldev)
|
||||
#define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \
|
||||
0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB)
|
||||
|
||||
static struct mei_cl_device_id mei_wdt_tbl[] = {
|
||||
static const struct mei_cl_device_id mei_wdt_tbl[] = {
|
||||
{ .uuid = MEI_UUID_WD, .version = MEI_CL_VERSION_ANY },
|
||||
/* required last entry */
|
||||
{ }
|
||||
|
@ -155,7 +155,9 @@ static const struct watchdog_ops meson_wdt_ops = {
|
||||
|
||||
static const struct of_device_id meson_wdt_dt_ids[] = {
|
||||
{ .compatible = "amlogic,meson6-wdt", .data = &meson6_wdt_data },
|
||||
{ .compatible = "amlogic,meson8-wdt", .data = &meson6_wdt_data },
|
||||
{ .compatible = "amlogic,meson8b-wdt", .data = &meson8b_wdt_data },
|
||||
{ .compatible = "amlogic,meson8m2-wdt", .data = &meson8b_wdt_data },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, meson_wdt_dt_ids);
|
||||
|
@ -105,7 +105,7 @@ static int mt7621_wdt_bootcause(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct watchdog_info mt7621_wdt_info = {
|
||||
static const struct watchdog_info mt7621_wdt_info = {
|
||||
.identity = "Mediatek Watchdog",
|
||||
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
|
||||
};
|
||||
@ -135,7 +135,7 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(mt7621_wdt_base))
|
||||
return PTR_ERR(mt7621_wdt_base);
|
||||
|
||||
mt7621_wdt_reset = devm_reset_control_get(&pdev->dev, NULL);
|
||||
mt7621_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||
if (!IS_ERR(mt7621_wdt_reset))
|
||||
reset_control_deassert(mt7621_wdt_reset);
|
||||
|
||||
|
@ -51,9 +51,16 @@ struct xwdt_device {
|
||||
|
||||
static int xilinx_wdt_start(struct watchdog_device *wdd)
|
||||
{
|
||||
int ret;
|
||||
u32 control_status_reg;
|
||||
struct xwdt_device *xdev = watchdog_get_drvdata(wdd);
|
||||
|
||||
ret = clk_enable(xdev->clk);
|
||||
if (ret) {
|
||||
dev_err(wdd->parent, "Failed to enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
spin_lock(&xdev->spinlock);
|
||||
|
||||
/* Clean previous status and enable the watchdog timer */
|
||||
@ -85,6 +92,9 @@ static int xilinx_wdt_stop(struct watchdog_device *wdd)
|
||||
iowrite32(0, xdev->base + XWT_TWCSR1_OFFSET);
|
||||
|
||||
spin_unlock(&xdev->spinlock);
|
||||
|
||||
clk_disable(xdev->clk);
|
||||
|
||||
pr_info("Stopped!\n");
|
||||
|
||||
return 0;
|
||||
@ -167,11 +177,6 @@ static int xwdt_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(xdev->base))
|
||||
return PTR_ERR(xdev->base);
|
||||
|
||||
rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency", &pfreq);
|
||||
if (rc)
|
||||
dev_warn(&pdev->dev,
|
||||
"The watchdog clock frequency cannot be obtained\n");
|
||||
|
||||
rc = of_property_read_u32(pdev->dev.of_node, "xlnx,wdt-interval",
|
||||
&xdev->wdt_interval);
|
||||
if (rc)
|
||||
@ -186,6 +191,26 @@ static int xwdt_probe(struct platform_device *pdev)
|
||||
|
||||
watchdog_set_nowayout(xilinx_wdt_wdd, enable_once);
|
||||
|
||||
xdev->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(xdev->clk)) {
|
||||
if (PTR_ERR(xdev->clk) != -ENOENT)
|
||||
return PTR_ERR(xdev->clk);
|
||||
|
||||
/*
|
||||
* Clock framework support is optional, continue on
|
||||
* anyways if we don't find a matching clock.
|
||||
*/
|
||||
xdev->clk = NULL;
|
||||
|
||||
rc = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
|
||||
&pfreq);
|
||||
if (rc)
|
||||
dev_warn(&pdev->dev,
|
||||
"The watchdog clock freq cannot be obtained\n");
|
||||
} else {
|
||||
pfreq = clk_get_rate(xdev->clk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Twice of the 2^wdt_interval / freq because the first wdt overflow is
|
||||
* ignored (interrupt), reset is only generated at second wdt overflow
|
||||
@ -197,14 +222,6 @@ static int xwdt_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&xdev->spinlock);
|
||||
watchdog_set_drvdata(xilinx_wdt_wdd, xdev);
|
||||
|
||||
xdev->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(xdev->clk)) {
|
||||
if (PTR_ERR(xdev->clk) == -ENOENT)
|
||||
xdev->clk = NULL;
|
||||
else
|
||||
return PTR_ERR(xdev->clk);
|
||||
}
|
||||
|
||||
rc = clk_prepare_enable(xdev->clk);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "unable to enable clock\n");
|
||||
@ -223,6 +240,8 @@ static int xwdt_probe(struct platform_device *pdev)
|
||||
goto err_clk_disable;
|
||||
}
|
||||
|
||||
clk_disable(xdev->clk);
|
||||
|
||||
dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n",
|
||||
xdev->base, xilinx_wdt_wdd->timeout);
|
||||
|
||||
@ -245,6 +264,43 @@ static int xwdt_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* xwdt_suspend - Suspend the device.
|
||||
*
|
||||
* @dev: handle to the device structure.
|
||||
* Return: 0 always.
|
||||
*/
|
||||
static int __maybe_unused xwdt_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct xwdt_device *xdev = platform_get_drvdata(pdev);
|
||||
|
||||
if (watchdog_active(&xdev->xilinx_wdt_wdd))
|
||||
xilinx_wdt_stop(&xdev->xilinx_wdt_wdd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* xwdt_resume - Resume the device.
|
||||
*
|
||||
* @dev: handle to the device structure.
|
||||
* Return: 0 on success, errno otherwise.
|
||||
*/
|
||||
static int __maybe_unused xwdt_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct xwdt_device *xdev = platform_get_drvdata(pdev);
|
||||
int ret = 0;
|
||||
|
||||
if (watchdog_active(&xdev->xilinx_wdt_wdd))
|
||||
ret = xilinx_wdt_start(&xdev->xilinx_wdt_wdd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(xwdt_pm_ops, xwdt_suspend, xwdt_resume);
|
||||
|
||||
/* Match table for of_platform binding */
|
||||
static const struct of_device_id xwdt_of_match[] = {
|
||||
{ .compatible = "xlnx,xps-timebase-wdt-1.00.a", },
|
||||
@ -259,6 +315,7 @@ static struct platform_driver xwdt_driver = {
|
||||
.driver = {
|
||||
.name = WATCHDOG_NAME,
|
||||
.of_match_table = xwdt_of_match,
|
||||
.pm = &xwdt_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||
#define USB_PCWD_PRODUCT_ID 0x1140
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
static struct usb_device_id usb_pcwd_table[] = {
|
||||
static const struct usb_device_id usb_pcwd_table[] = {
|
||||
{ USB_DEVICE(USB_PCWD_VENDOR_ID, USB_PCWD_PRODUCT_ID) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
@ -162,6 +162,8 @@ static int qcom_wdt_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENOMEM;
|
||||
|
||||
/* We use CPU0's DGT for the watchdog */
|
||||
if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Watchdog driver for Renesas WDT watchdog
|
||||
*
|
||||
* Copyright (C) 2015-16 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
|
||||
* Copyright (C) 2015-16 Renesas Electronics Corporation
|
||||
* Copyright (C) 2015-17 Wolfram Sang, Sang Engineering <wsa@sang-engineering.com>
|
||||
* Copyright (C) 2015-17 Renesas Electronics Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
@ -23,10 +23,22 @@
|
||||
#define RWTCSRA_WOVF BIT(4)
|
||||
#define RWTCSRA_WRFLG BIT(5)
|
||||
#define RWTCSRA_TME BIT(7)
|
||||
#define RWTCSRB 8
|
||||
|
||||
#define RWDT_DEFAULT_TIMEOUT 60U
|
||||
|
||||
static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024 };
|
||||
/*
|
||||
* In probe, clk_rate is checked to be not more than 16 bit * biggest clock
|
||||
* divider (12 bits). d is only a factor to fully utilize the WDT counter and
|
||||
* will not exceed its 16 bits. Thus, no overflow, we stay below 32 bits.
|
||||
*/
|
||||
#define MUL_BY_CLKS_PER_SEC(p, d) \
|
||||
DIV_ROUND_UP((d) * (p)->clk_rate, clk_divs[(p)->cks])
|
||||
|
||||
/* d is 16 bit, clk_divs 12 bit -> no 32 bit overflow */
|
||||
#define DIV_BY_CLKS_PER_SEC(p, d) ((d) * clk_divs[(p)->cks] / (p)->clk_rate)
|
||||
|
||||
static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 };
|
||||
|
||||
static bool nowayout = WATCHDOG_NOWAYOUT;
|
||||
module_param(nowayout, bool, 0);
|
||||
@ -36,8 +48,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||
struct rwdt_priv {
|
||||
void __iomem *base;
|
||||
struct watchdog_device wdev;
|
||||
struct clk *clk;
|
||||
unsigned int clks_per_sec;
|
||||
unsigned long clk_rate;
|
||||
u8 cks;
|
||||
};
|
||||
|
||||
@ -55,7 +66,7 @@ static int rwdt_init_timeout(struct watchdog_device *wdev)
|
||||
{
|
||||
struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
|
||||
rwdt_write(priv, 65536 - wdev->timeout * priv->clks_per_sec, RWTCNT);
|
||||
rwdt_write(priv, 65536 - MUL_BY_CLKS_PER_SEC(priv, wdev->timeout), RWTCNT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -64,8 +75,9 @@ static int rwdt_start(struct watchdog_device *wdev)
|
||||
{
|
||||
struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
|
||||
clk_prepare_enable(priv->clk);
|
||||
pm_runtime_get_sync(wdev->parent);
|
||||
|
||||
rwdt_write(priv, 0, RWTCSRB);
|
||||
rwdt_write(priv, priv->cks, RWTCSRA);
|
||||
rwdt_init_timeout(wdev);
|
||||
|
||||
@ -82,7 +94,7 @@ static int rwdt_stop(struct watchdog_device *wdev)
|
||||
struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
|
||||
rwdt_write(priv, priv->cks, RWTCSRA);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
pm_runtime_put(wdev->parent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -92,7 +104,7 @@ static unsigned int rwdt_get_timeleft(struct watchdog_device *wdev)
|
||||
struct rwdt_priv *priv = watchdog_get_drvdata(wdev);
|
||||
u16 val = readw_relaxed(priv->base + RWTCNT);
|
||||
|
||||
return DIV_ROUND_CLOSEST(65536 - val, priv->clks_per_sec);
|
||||
return DIV_BY_CLKS_PER_SEC(priv, 65536 - val);
|
||||
}
|
||||
|
||||
static const struct watchdog_info rwdt_ident = {
|
||||
@ -112,8 +124,8 @@ static int rwdt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rwdt_priv *priv;
|
||||
struct resource *res;
|
||||
unsigned long rate;
|
||||
unsigned int clks_per_sec;
|
||||
struct clk *clk;
|
||||
unsigned long clks_per_sec;
|
||||
int ret, i;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
@ -125,36 +137,40 @@ static int rwdt_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(priv->base))
|
||||
return PTR_ERR(priv->base);
|
||||
|
||||
priv->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(priv->clk))
|
||||
return PTR_ERR(priv->clk);
|
||||
clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
rate = clk_get_rate(priv->clk);
|
||||
if (!rate)
|
||||
return -ENOENT;
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
priv->clk_rate = clk_get_rate(clk);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
if (!priv->clk_rate) {
|
||||
ret = -ENOENT;
|
||||
goto out_pm_disable;
|
||||
}
|
||||
|
||||
for (i = ARRAY_SIZE(clk_divs) - 1; i >= 0; i--) {
|
||||
clks_per_sec = DIV_ROUND_UP(rate, clk_divs[i]);
|
||||
if (clks_per_sec) {
|
||||
priv->clks_per_sec = clks_per_sec;
|
||||
clks_per_sec = priv->clk_rate / clk_divs[i];
|
||||
if (clks_per_sec && clks_per_sec < 65536) {
|
||||
priv->cks = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!clks_per_sec) {
|
||||
if (i < 0) {
|
||||
dev_err(&pdev->dev, "Can't find suitable clock divider\n");
|
||||
return -ERANGE;
|
||||
ret = -ERANGE;
|
||||
goto out_pm_disable;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
|
||||
priv->wdev.info = &rwdt_ident,
|
||||
priv->wdev.ops = &rwdt_ops,
|
||||
priv->wdev.parent = &pdev->dev;
|
||||
priv->wdev.min_timeout = 1;
|
||||
priv->wdev.max_timeout = 65536 / clks_per_sec;
|
||||
priv->wdev.max_timeout = DIV_BY_CLKS_PER_SEC(priv, 65536);
|
||||
priv->wdev.timeout = min(priv->wdev.max_timeout, RWDT_DEFAULT_TIMEOUT);
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
@ -167,13 +183,14 @@ static int rwdt_probe(struct platform_device *pdev)
|
||||
dev_warn(&pdev->dev, "Specified timeout value invalid, using default\n");
|
||||
|
||||
ret = watchdog_register_device(&priv->wdev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto out_pm_disable;
|
||||
|
||||
return 0;
|
||||
|
||||
out_pm_disable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rwdt_remove(struct platform_device *pdev)
|
||||
@ -181,7 +198,6 @@ static int rwdt_remove(struct platform_device *pdev)
|
||||
struct rwdt_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
watchdog_unregister_device(&priv->wdev);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
@ -119,7 +119,7 @@ static int rt288x_wdt_bootcause(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct watchdog_info rt288x_wdt_info = {
|
||||
static const struct watchdog_info rt288x_wdt_info = {
|
||||
.identity = "Ralink Watchdog",
|
||||
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
|
||||
};
|
||||
@ -152,7 +152,7 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(rt288x_wdt_clk))
|
||||
return PTR_ERR(rt288x_wdt_clk);
|
||||
|
||||
rt288x_wdt_reset = devm_reset_control_get(&pdev->dev, NULL);
|
||||
rt288x_wdt_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||
if (!IS_ERR(rt288x_wdt_reset))
|
||||
reset_control_deassert(rt288x_wdt_reset);
|
||||
|
||||
|
@ -342,7 +342,7 @@ static int __init sc1200wdt_probe(void)
|
||||
|
||||
#if defined CONFIG_PNP
|
||||
|
||||
static struct pnp_device_id scl200wdt_pnp_devices[] = {
|
||||
static const struct pnp_device_id scl200wdt_pnp_devices[] = {
|
||||
/* National Semiconductor PC87307/PC97307 watchdog component */
|
||||
{.id = "NSC0800", .driver_data = 0},
|
||||
{.id = ""},
|
||||
|
@ -281,7 +281,7 @@ static int __maybe_unused sp805_wdt_resume(struct device *dev)
|
||||
static SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend,
|
||||
sp805_wdt_resume);
|
||||
|
||||
static struct amba_id sp805_wdt_ids[] = {
|
||||
static const struct amba_id sp805_wdt_ids[] = {
|
||||
{
|
||||
.id = 0x00141805,
|
||||
.mask = 0x00ffffff,
|
||||
|
@ -140,7 +140,7 @@ static const struct watchdog_info stm32_iwdg_info = {
|
||||
.identity = "STM32 Independent Watchdog",
|
||||
};
|
||||
|
||||
static struct watchdog_ops stm32_iwdg_ops = {
|
||||
static const struct watchdog_ops stm32_iwdg_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.start = stm32_iwdg_start,
|
||||
.ping = stm32_iwdg_ping,
|
||||
|
@ -112,7 +112,7 @@ static const struct watchdog_info ts72xx_wdt_ident = {
|
||||
.identity = "TS-72XX WDT",
|
||||
};
|
||||
|
||||
static struct watchdog_ops ts72xx_wdt_ops = {
|
||||
static const struct watchdog_ops ts72xx_wdt_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.start = ts72xx_wdt_start,
|
||||
.stop = ts72xx_wdt_stop,
|
||||
|
@ -429,7 +429,7 @@ static int __init wdt_init(void)
|
||||
{
|
||||
int ret;
|
||||
int chip;
|
||||
const char * const chip_name[] = {
|
||||
static const char * const chip_name[] = {
|
||||
"W83627HF",
|
||||
"W83627S",
|
||||
"W83697HF",
|
||||
|
@ -737,7 +737,7 @@ static int ziirave_wdt_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_device_id ziirave_wdt_id[] = {
|
||||
static const struct i2c_device_id ziirave_wdt_id[] = {
|
||||
{ "rave-wdt", 0 },
|
||||
{ }
|
||||
};
|
||||
|
@ -229,7 +229,7 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
|
||||
}
|
||||
clk_set_rate(wdt->clock, ZX2967_WDT_CLK_FREQ);
|
||||
|
||||
rstc = devm_reset_control_get(dev, NULL);
|
||||
rstc = devm_reset_control_get_exclusive(dev, NULL);
|
||||
if (IS_ERR(rstc)) {
|
||||
dev_err(dev, "failed to get rstc");
|
||||
ret = PTR_ERR(rstc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user