Merge tag 'linux-watchdog-5.2-rc1' of git://www.linux-watchdog.org/linux-watchdog

Pull watchdog updates from Wim Van Sebroeck:

 - a new watchdog driver for the ROHM BD70528 watchdog block

 - a new watchdog driver for the i.MX system controller watchdog

 - conversions to use device managed functions and other improvements

 - refactor watchdog_init_timeout

 - make watchdog core configurable as module

 - pretimeout governors improvements

 - a lot of other fixes

* tag 'linux-watchdog-5.2-rc1' of git://www.linux-watchdog.org/linux-watchdog: (114 commits)
  watchdog: Enforce that at least one pretimeout governor is enabled
  watchdog: stm32: add dynamic prescaler support
  watchdog: Improve Kconfig entry ordering and dependencies
  watchdog: npcm: Enable modular builds
  watchdog: Make watchdog core configurable as module
  watchdog: Move pretimeout governor configuration up
  watchdog: Use depends instead of select for pretimeout governors
  watchdog: rtd119x: drop unused module.h include
  watchdog: intel_scu: make it explicitly non-modular
  watchdog: coh901327: make it explicitly non-modular
  watchdog: ziirave_wdt: drop warning after calling watchdog_init_timeout
  watchdog: xen_wdt: drop warning after calling watchdog_init_timeout
  watchdog: stm32_iwdg: drop warning after calling watchdog_init_timeout
  watchdog: st_lpc_wdt: drop warning after calling watchdog_init_timeout
  watchdog: sp5100_tco: drop warning after calling watchdog_init_timeout
  watchdog: renesas_wdt: drop warning after calling watchdog_init_timeout
  watchdog: nic7018_wdt: drop warning after calling watchdog_init_timeout
  watchdog: ni903x_wdt: drop warning after calling watchdog_init_timeout
  watchdog: imx_sc_wdt: drop warning after calling watchdog_init_timeout
  watchdog: i6300esb: drop warning after calling watchdog_init_timeout
  ...
This commit is contained in:
Linus Torvalds
2019-05-13 09:20:42 -04:00
99 changed files with 1490 additions and 1537 deletions

View File

@@ -0,0 +1,24 @@
* Freescale i.MX System Controller Watchdog
i.MX system controller watchdog is for i.MX SoCs with system controller inside,
the watchdog is managed by system controller, users can ONLY communicate with
system controller from secure mode for watchdog operations, so Linux i.MX system
controller watchdog driver will call ARM SMC API and trap into ARM-Trusted-Firmware
for watchdog operations, ARM-Trusted-Firmware is running at secure EL3 mode and
it will request system controller to execute the watchdog operation passed from
Linux kernel.
Required properties:
- compatible: Should be :
"fsl,imx8qxp-sc-wdt"
followed by "fsl,imx-sc-wdt";
Optional properties:
- timeout-sec : Contains the watchdog timeout in seconds.
Examples:
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>;
};

View File

@@ -9,6 +9,7 @@ Required properties:
"mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
"mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
- reg : Specifies base physical address and size of the registers.

View File

@@ -30,7 +30,7 @@ menuconfig WATCHDOG
if WATCHDOG
config WATCHDOG_CORE
bool "WatchDog Timer Driver Core"
tristate "WatchDog Timer Driver Core"
---help---
Say Y here if you want to use the new watchdog timer driver core.
This driver provides a framework for all watchdog timer drivers
@@ -63,6 +63,66 @@ config WATCHDOG_SYSFS
Say Y here if you want to enable watchdog device status read through
sysfs attributes.
comment "Watchdog Pretimeout Governors"
config WATCHDOG_PRETIMEOUT_GOV
bool "Enable watchdog pretimeout governors"
depends on WATCHDOG_CORE
help
The option allows to select watchdog pretimeout governors.
config WATCHDOG_PRETIMEOUT_GOV_SEL
tristate
depends on WATCHDOG_PRETIMEOUT_GOV
default m
select WATCHDOG_PRETIMEOUT_GOV_PANIC if WATCHDOG_PRETIMEOUT_GOV_NOOP=n
if WATCHDOG_PRETIMEOUT_GOV
config WATCHDOG_PRETIMEOUT_GOV_NOOP
tristate "Noop watchdog pretimeout governor"
depends on WATCHDOG_CORE
default WATCHDOG_CORE
help
Noop watchdog pretimeout governor, only an informational
message is added to kernel log buffer.
config WATCHDOG_PRETIMEOUT_GOV_PANIC
tristate "Panic watchdog pretimeout governor"
depends on WATCHDOG_CORE
default WATCHDOG_CORE
help
Panic watchdog pretimeout governor, on watchdog pretimeout
event put the kernel into panic.
choice
prompt "Default Watchdog Pretimeout Governor"
default WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
help
This option selects a default watchdog pretimeout governor.
The governor takes its action, if a watchdog is capable
to report a pretimeout event.
config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP
bool "noop"
depends on WATCHDOG_PRETIMEOUT_GOV_NOOP
help
Use noop watchdog pretimeout governor by default. If noop
governor is selected by a user, write a short message to
the kernel log buffer and don't do any system changes.
config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
bool "panic"
depends on WATCHDOG_PRETIMEOUT_GOV_PANIC
help
Use panic watchdog pretimeout governor by default, if
a watchdog pretimeout event happens, consider that
a watchdog feeder is dead and reboot is unavoidable.
endchoice
endif # WATCHDOG_PRETIMEOUT_GOV
#
# General Watchdog drivers
#
@@ -90,6 +150,18 @@ config SOFT_WATCHDOG_PRETIMEOUT
watchdog. Be aware that governors might affect the watchdog because it
is purely software, e.g. the panic governor will stall it!
config BD70528_WATCHDOG
tristate "ROHM BD70528 PMIC Watchdog"
depends on MFD_ROHM_BD70528
select WATCHDOG_CORE
help
Support for the watchdog in the ROHM BD70528 PMIC. Watchdog trigger
cause system reset.
Say Y here to include support for the ROHM BD70528 watchdog.
Alternatively say M to compile the driver as a module,
which will be called bd70528_wdt.
config DA9052_WATCHDOG
tristate "Dialog DA9052 Watchdog"
depends on PMIC_DA9052 || COMPILE_TEST
@@ -552,7 +624,7 @@ config COH901327_WATCHDOG
compiled as a module.
config NPCM7XX_WATCHDOG
bool "Nuvoton NPCM750 watchdog"
tristate "Nuvoton NPCM750 watchdog"
depends on ARCH_NPCM || COMPILE_TEST
default y if ARCH_NPCM7XX
select WATCHDOG_CORE
@@ -641,6 +713,22 @@ config IMX2_WDT
To compile this driver as a module, choose M here: the
module will be called imx2_wdt.
config IMX_SC_WDT
tristate "IMX SC Watchdog"
depends on HAVE_ARM_SMCCC
select WATCHDOG_CORE
help
This is the driver for the system controller watchdog
on the NXP i.MX SoCs with system controller inside, the
watchdog driver will call ARM SMC API and trap into
ARM-Trusted-Firmware for operations, ARM-Trusted-Firmware
will request system controller to execute the operations.
If you have one of these processors and wish to have
watchdog support enabled, say Y, otherwise say N.
To compile this driver as a module, choose M here: the
module will be called imx_sc_wdt.
config UX500_WATCHDOG
tristate "ST-Ericsson Ux500 watchdog"
depends on MFD_DB8500_PRCMU
@@ -1179,6 +1267,15 @@ config HP_WATCHDOG
To compile this driver as a module, choose M here: the module will be
called hpwdt.
config HPWDT_NMI_DECODING
bool "NMI support for the HP ProLiant iLO2+ Hardware Watchdog Timer"
depends on HP_WATCHDOG
default y
help
Enables the NMI handler for the watchdog pretimeout NMI and the iLO
"Generate NMI to System" virtual button. When an NMI is claimed
by the driver, panic is called.
config KEMPLD_WDT
tristate "Kontron COM Watchdog Timer"
depends on MFD_KEMPLD
@@ -1190,15 +1287,6 @@ config KEMPLD_WDT
This driver can also be built as a module. If so, the module will be
called kempld_wdt.
config HPWDT_NMI_DECODING
bool "NMI support for the HP ProLiant iLO2+ Hardware Watchdog Timer"
depends on HP_WATCHDOG
default y
help
Enables the NMI handler for the watchdog pretimeout NMI and the iLO
"Generate NMI to System" virtual button. When an NMI is claimed
by the driver, panic is called.
config SC1200_WDT
tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
depends on X86
@@ -1647,7 +1735,7 @@ config BCM_KONA_WDT
config BCM_KONA_WDT_DEBUG
bool "DEBUGFS support for BCM Kona Watchdog"
depends on BCM_KONA_WDT || COMPILE_TEST
depends on BCM_KONA_WDT
help
If enabled, adds /sys/kernel/debug/bcm_kona_wdt/info which provides
access to the driver's internal data structures as well as watchdog
@@ -2024,53 +2112,4 @@ config USBPCWATCHDOG
Most people will say N.
comment "Watchdog Pretimeout Governors"
config WATCHDOG_PRETIMEOUT_GOV
bool "Enable watchdog pretimeout governors"
help
The option allows to select watchdog pretimeout governors.
if WATCHDOG_PRETIMEOUT_GOV
choice
prompt "Default Watchdog Pretimeout Governor"
default WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
help
This option selects a default watchdog pretimeout governor.
The governor takes its action, if a watchdog is capable
to report a pretimeout event.
config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP
bool "noop"
select WATCHDOG_PRETIMEOUT_GOV_NOOP
help
Use noop watchdog pretimeout governor by default. If noop
governor is selected by a user, write a short message to
the kernel log buffer and don't do any system changes.
config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC
bool "panic"
select WATCHDOG_PRETIMEOUT_GOV_PANIC
help
Use panic watchdog pretimeout governor by default, if
a watchdog pretimeout event happens, consider that
a watchdog feeder is dead and reboot is unavoidable.
endchoice
config WATCHDOG_PRETIMEOUT_GOV_NOOP
tristate "Noop watchdog pretimeout governor"
help
Noop watchdog pretimeout governor, only an informational
message is added to kernel log buffer.
config WATCHDOG_PRETIMEOUT_GOV_PANIC
tristate "Panic watchdog pretimeout governor"
help
Panic watchdog pretimeout governor, on watchdog pretimeout
event put the kernel into panic.
endif # WATCHDOG_PRETIMEOUT_GOV
endif # WATCHDOG

View File

@@ -68,6 +68,7 @@ obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
obj-$(CONFIG_TS4800_WATCHDOG) += ts4800_wdt.o
obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
obj-$(CONFIG_IMX_SC_WDT) += imx_sc_wdt.o
obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
@@ -205,6 +206,7 @@ obj-$(CONFIG_WATCHDOG_SUN4V) += sun4v_wdt.o
obj-$(CONFIG_XEN_WDT) += xen_wdt.o
# Architecture Independent
obj-$(CONFIG_BD70528_WATCHDOG) += bd70528_wdt.o
obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o
obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o

View File

@@ -277,8 +277,8 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return -EINVAL;
timeout = new_timeout;
wdt_keepalive();
/* Fall through */
}
/* Fall through */
case WDIOC_GETTIMEOUT:
return put_user(timeout, p);
default:

View File

@@ -244,6 +244,11 @@ static const struct watchdog_ops armada_37xx_wdt_ops = {
.get_timeleft = armada_37xx_wdt_get_timeleft,
};
static void armada_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static int armada_37xx_wdt_probe(struct platform_device *pdev)
{
struct armada_37xx_watchdog *dev;
@@ -278,12 +283,14 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev)
ret = clk_prepare_enable(dev->clk);
if (ret)
return ret;
ret = devm_add_action_or_reset(&pdev->dev,
armada_clk_disable_unprepare, dev->clk);
if (ret)
return ret;
dev->clk_rate = clk_get_rate(dev->clk);
if (!dev->clk_rate) {
ret = -EINVAL;
goto disable_clk;
}
if (!dev->clk_rate)
return -EINVAL;
/*
* Since the timeout in seconds is given as 32 bit unsigned int, and
@@ -307,35 +314,15 @@ static int armada_37xx_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &dev->wdt.status);
watchdog_set_nowayout(&dev->wdt, nowayout);
ret = watchdog_register_device(&dev->wdt);
watchdog_stop_on_reboot(&dev->wdt);
ret = devm_watchdog_register_device(&pdev->dev, &dev->wdt);
if (ret)
goto disable_clk;
return ret;
dev_info(&pdev->dev, "Initial timeout %d sec%s\n",
dev->wdt.timeout, nowayout ? ", nowayout" : "");
return 0;
disable_clk:
clk_disable_unprepare(dev->clk);
return ret;
}
static int armada_37xx_wdt_remove(struct platform_device *pdev)
{
struct watchdog_device *wdt = platform_get_drvdata(pdev);
struct armada_37xx_watchdog *dev = watchdog_get_drvdata(wdt);
watchdog_unregister_device(wdt);
clk_disable_unprepare(dev->clk);
return 0;
}
static void armada_37xx_wdt_shutdown(struct platform_device *pdev)
{
struct watchdog_device *wdt = platform_get_drvdata(pdev);
armada_37xx_wdt_stop(wdt);
}
static int __maybe_unused armada_37xx_wdt_suspend(struct device *dev)
@@ -370,8 +357,6 @@ MODULE_DEVICE_TABLE(of, armada_37xx_wdt_match);
static struct platform_driver armada_37xx_wdt_driver = {
.probe = armada_37xx_wdt_probe,
.remove = armada_37xx_wdt_remove,
.shutdown = armada_37xx_wdt_shutdown,
.driver = {
.name = "armada_37xx_wdt",
.of_match_table = of_match_ptr(armada_37xx_wdt_match),

View File

@@ -196,6 +196,11 @@ static const struct watchdog_ops asm9260_wdt_ops = {
.restart = asm9260_restart,
};
static void asm9260_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static int asm9260_wdt_get_dt_clks(struct asm9260_wdt_priv *priv)
{
int err;
@@ -219,26 +224,32 @@ static int asm9260_wdt_get_dt_clks(struct asm9260_wdt_priv *priv)
dev_err(priv->dev, "Failed to enable ahb_clk!\n");
return err;
}
err = devm_add_action_or_reset(priv->dev,
asm9260_clk_disable_unprepare,
priv->clk_ahb);
if (err)
return err;
err = clk_set_rate(priv->clk, CLOCK_FREQ);
if (err) {
clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed to set rate!\n");
return err;
}
err = clk_prepare_enable(priv->clk);
if (err) {
clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed to enable clk!\n");
return err;
}
err = devm_add_action_or_reset(priv->dev,
asm9260_clk_disable_unprepare,
priv->clk);
if (err)
return err;
/* wdt has internal divider */
clk = clk_get_rate(priv->clk);
if (!clk) {
clk_disable_unprepare(priv->clk);
clk_disable_unprepare(priv->clk_ahb);
dev_err(priv->dev, "Failed, clk is 0!\n");
return -EINVAL;
}
@@ -274,25 +285,23 @@ static void asm9260_wdt_get_dt_mode(struct asm9260_wdt_priv *priv)
static int asm9260_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct asm9260_wdt_priv *priv;
struct watchdog_device *wdd;
struct resource *res;
int ret;
static const char * const mode_name[] = { "hw", "sw", "debug", };
priv = devm_kzalloc(&pdev->dev, sizeof(struct asm9260_wdt_priv),
GFP_KERNEL);
priv = devm_kzalloc(dev, sizeof(struct asm9260_wdt_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = &pdev->dev;
priv->dev = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->iobase = devm_ioremap_resource(&pdev->dev, res);
priv->iobase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->iobase))
return PTR_ERR(priv->iobase);
priv->rst = devm_reset_control_get_exclusive(&pdev->dev, "wdt_rst");
priv->rst = devm_reset_control_get_exclusive(dev, "wdt_rst");
if (IS_ERR(priv->rst))
return PTR_ERR(priv->rst);
@@ -305,7 +314,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
wdd->ops = &asm9260_wdt_ops;
wdd->min_timeout = 1;
wdd->max_timeout = BM_WDTC_MAX(priv->wdt_freq);
wdd->parent = &pdev->dev;
wdd->parent = dev;
watchdog_set_drvdata(wdd, priv);
@@ -315,7 +324,7 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
* the max instead.
*/
wdd->timeout = ASM9260_WDT_DEFAULT_TIMEOUT;
watchdog_init_timeout(wdd, 0, &pdev->dev);
watchdog_init_timeout(wdd, 0, dev);
asm9260_wdt_get_dt_mode(priv);
@@ -327,49 +336,25 @@ static int asm9260_wdt_probe(struct platform_device *pdev)
* Not all supported platforms specify an interrupt for the
* watchdog, so let's make it optional.
*/
ret = devm_request_irq(&pdev->dev, priv->irq,
asm9260_wdt_irq, 0, pdev->name, priv);
ret = devm_request_irq(dev, priv->irq, asm9260_wdt_irq, 0,
pdev->name, priv);
if (ret < 0)
dev_warn(&pdev->dev, "failed to request IRQ\n");
dev_warn(dev, "failed to request IRQ\n");
}
watchdog_set_restart_priority(wdd, 128);
ret = watchdog_register_device(wdd);
watchdog_stop_on_reboot(wdd);
watchdog_stop_on_unregister(wdd);
ret = devm_watchdog_register_device(dev, wdd);
if (ret)
goto clk_off;
return ret;
platform_set_drvdata(pdev, priv);
dev_info(&pdev->dev, "Watchdog enabled (timeout: %d sec, mode: %s)\n",
dev_info(dev, "Watchdog enabled (timeout: %d sec, mode: %s)\n",
wdd->timeout, mode_name[priv->mode]);
return 0;
clk_off:
clk_disable_unprepare(priv->clk);
clk_disable_unprepare(priv->clk_ahb);
return ret;
}
static void asm9260_wdt_shutdown(struct platform_device *pdev)
{
struct asm9260_wdt_priv *priv = platform_get_drvdata(pdev);
asm9260_wdt_disable(&priv->wdd);
}
static int asm9260_wdt_remove(struct platform_device *pdev)
{
struct asm9260_wdt_priv *priv = platform_get_drvdata(pdev);
asm9260_wdt_disable(&priv->wdd);
watchdog_unregister_device(&priv->wdd);
clk_disable_unprepare(priv->clk);
clk_disable_unprepare(priv->clk_ahb);
return 0;
}
static const struct of_device_id asm9260_wdt_of_match[] = {
@@ -384,8 +369,6 @@ static struct platform_driver asm9260_wdt_driver = {
.of_match_table = asm9260_wdt_of_match,
},
.probe = asm9260_wdt_probe,
.remove = asm9260_wdt_remove,
.shutdown = asm9260_wdt_shutdown,
};
module_platform_driver(asm9260_wdt_driver);

View File

@@ -187,22 +187,21 @@ static const struct watchdog_info aspeed_wdt_info = {
static int aspeed_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
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;
u32 status;
int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
wdt = devm_kzalloc(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);
wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
@@ -214,12 +213,12 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
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.parent = dev;
wdt->wdd.timeout = WDT_DEFAULT_TIMEOUT;
watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
watchdog_init_timeout(&wdt->wdd, 0, dev);
np = pdev->dev.of_node;
np = dev->of_node;
ofdid = of_match_node(aspeed_wdt_of_table, np);
if (!ofdid)
@@ -288,11 +287,11 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
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);
dev_err(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);
dev_info(dev, "Pulse duration set to %uus\n",
duration);
}
/*
@@ -314,9 +313,9 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
wdt->wdd.bootstatus = WDIOF_CARDRESET;
ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
ret = devm_watchdog_register_device(dev, &wdt->wdd);
if (ret) {
dev_err(&pdev->dev, "failed to register\n");
dev_err(dev, "failed to register\n");
return ret;
}

View File

@@ -327,7 +327,6 @@ static inline int of_at91wdt_init(struct device_node *np, struct at91wdt *wdt)
static int __init at91wdt_probe(struct platform_device *pdev)
{
struct resource *r;
int err;
struct at91wdt *wdt;
@@ -346,8 +345,7 @@ static int __init at91wdt_probe(struct platform_device *pdev)
wdt->wdd.min_timeout = 1;
wdt->wdd.max_timeout = 0xFFFF;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
wdt->base = devm_ioremap_resource(&pdev->dev, r);
wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);

View File

@@ -250,15 +250,13 @@ static struct miscdevice ath79_wdt_miscdev = {
static int ath79_wdt_probe(struct platform_device *pdev)
{
struct resource *res;
u32 ctrl;
int err;
if (wdt_base)
return -EBUSY;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
wdt_base = devm_ioremap_resource(&pdev->dev, res);
wdt_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt_base))
return PTR_ERR(wdt_base);

View File

@@ -125,80 +125,57 @@ static const struct of_device_id atlas7_wdt_ids[] = {
{}
};
static void atlas7_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static int atlas7_wdt_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct atlas7_wdog *wdt;
struct resource *res;
struct clk *clk;
int ret;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
wdt = devm_kzalloc(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);
wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
clk = of_clk_get(np, 0);
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk))
return PTR_ERR(clk);
ret = clk_prepare_enable(clk);
if (ret) {
dev_err(&pdev->dev, "clk enable failed\n");
goto err;
dev_err(dev, "clk enable failed\n");
return ret;
}
ret = devm_add_action_or_reset(dev, atlas7_clk_disable_unprepare, clk);
if (ret)
return ret;
/* disable watchdog hardware */
writel(0, wdt->base + ATLAS7_WDT_CNT_CTRL);
wdt->tick_rate = clk_get_rate(clk);
if (!wdt->tick_rate) {
ret = -EINVAL;
goto err1;
}
if (!wdt->tick_rate)
return -EINVAL;
wdt->clk = clk;
atlas7_wdd.min_timeout = 1;
atlas7_wdd.max_timeout = UINT_MAX / wdt->tick_rate;
watchdog_init_timeout(&atlas7_wdd, 0, &pdev->dev);
watchdog_init_timeout(&atlas7_wdd, 0, dev);
watchdog_set_nowayout(&atlas7_wdd, nowayout);
watchdog_set_drvdata(&atlas7_wdd, wdt);
platform_set_drvdata(pdev, &atlas7_wdd);
ret = watchdog_register_device(&atlas7_wdd);
if (ret)
goto err1;
return 0;
err1:
clk_disable_unprepare(clk);
err:
clk_put(clk);
return ret;
}
static void atlas7_wdt_shutdown(struct platform_device *pdev)
{
struct watchdog_device *wdd = platform_get_drvdata(pdev);
struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
atlas7_wdt_disable(wdd);
clk_disable_unprepare(wdt->clk);
}
static int atlas7_wdt_remove(struct platform_device *pdev)
{
struct watchdog_device *wdd = platform_get_drvdata(pdev);
struct atlas7_wdog *wdt = watchdog_get_drvdata(wdd);
atlas7_wdt_shutdown(pdev);
clk_put(wdt->clk);
return 0;
watchdog_stop_on_reboot(&atlas7_wdd);
watchdog_stop_on_unregister(&atlas7_wdd);
return devm_watchdog_register_device(dev, &atlas7_wdd);
}
static int __maybe_unused atlas7_wdt_suspend(struct device *dev)
@@ -236,8 +213,6 @@ static struct platform_driver atlas7_wdt_driver = {
.of_match_table = atlas7_wdt_ids,
},
.probe = atlas7_wdt_probe,
.remove = atlas7_wdt_remove,
.shutdown = atlas7_wdt_shutdown,
};
module_platform_driver(atlas7_wdt_driver);

View File

@@ -177,7 +177,6 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
wdt = devm_kzalloc(dev, sizeof(struct bcm2835_wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
platform_set_drvdata(pdev, wdt);
spin_lock_init(&wdt->lock);

View File

@@ -107,11 +107,15 @@ static const struct watchdog_ops bcm7038_wdt_ops = {
.get_timeleft = bcm7038_wdt_get_timeleft,
};
static void bcm7038_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
static int bcm7038_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct bcm7038_watchdog *wdt;
struct resource *res;
int err;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
@@ -120,8 +124,7 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
wdt->base = devm_ioremap_resource(dev, res);
wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return PTR_ERR(wdt->base);
@@ -129,6 +132,11 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
/* If unable to get clock, use default frequency */
if (!IS_ERR(wdt->clk)) {
err = clk_prepare_enable(wdt->clk);
if (err)
return err;
err = devm_add_action_or_reset(dev,
bcm7038_clk_disable_unprepare,
wdt->clk);
if (err)
return err;
wdt->rate = clk_get_rate(wdt->clk);
@@ -148,10 +156,11 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
wdt->wdd.parent = dev;
watchdog_set_drvdata(&wdt->wdd, wdt);
err = watchdog_register_device(&wdt->wdd);
watchdog_stop_on_reboot(&wdt->wdd);
watchdog_stop_on_unregister(&wdt->wdd);
err = devm_watchdog_register_device(dev, &wdt->wdd);
if (err) {
dev_err(dev, "Failed to register watchdog device\n");
clk_disable_unprepare(wdt->clk);
return err;
}
@@ -160,19 +169,6 @@ static int bcm7038_wdt_probe(struct platform_device *pdev)
return 0;
}
static int bcm7038_wdt_remove(struct platform_device *pdev)
{
struct bcm7038_watchdog *wdt = platform_get_drvdata(pdev);
if (!nowayout)
bcm7038_wdt_stop(&wdt->wdd);
watchdog_unregister_device(&wdt->wdd);
clk_disable_unprepare(wdt->clk);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int bcm7038_wdt_suspend(struct device *dev)
{
@@ -198,14 +194,6 @@ static int bcm7038_wdt_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(bcm7038_wdt_pm_ops, bcm7038_wdt_suspend,
bcm7038_wdt_resume);
static void bcm7038_wdt_shutdown(struct platform_device *pdev)
{
struct bcm7038_watchdog *wdt = platform_get_drvdata(pdev);
if (watchdog_active(&wdt->wdd))
bcm7038_wdt_stop(&wdt->wdd);
}
static const struct of_device_id bcm7038_wdt_match[] = {
{ .compatible = "brcm,bcm7038-wdt" },
{},
@@ -214,8 +202,6 @@ MODULE_DEVICE_TABLE(of, bcm7038_wdt_match);
static struct platform_driver bcm7038_wdt_driver = {
.probe = bcm7038_wdt_probe,
.remove = bcm7038_wdt_remove,
.shutdown = bcm7038_wdt_shutdown,
.driver = {
.name = "bcm7038-wdt",
.of_match_table = bcm7038_wdt_match,

View File

@@ -271,16 +271,10 @@ static struct watchdog_device bcm_kona_wdt_wdd = {
.timeout = SECWDOG_MAX_COUNT >> SECWDOG_DEFAULT_RESOLUTION,
};
static void bcm_kona_wdt_shutdown(struct platform_device *pdev)
{
bcm_kona_wdt_stop(&bcm_kona_wdt_wdd);
}
static int bcm_kona_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct bcm_kona_wdt *wdt;
struct resource *res;
int ret;
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
@@ -289,8 +283,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
wdt->base = devm_ioremap_resource(dev, res);
wdt->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->base))
return -ENODEV;
@@ -303,7 +296,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, wdt);
watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
bcm_kona_wdt_wdd.parent = &pdev->dev;
bcm_kona_wdt_wdd.parent = dev;
ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
if (ret) {
@@ -311,7 +304,9 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
return ret;
}
ret = watchdog_register_device(&bcm_kona_wdt_wdd);
watchdog_stop_on_reboot(&bcm_kona_wdt_wdd);
watchdog_stop_on_unregister(&bcm_kona_wdt_wdd);
ret = devm_watchdog_register_device(dev, &bcm_kona_wdt_wdd);
if (ret) {
dev_err(dev, "Failed to register watchdog device");
return ret;
@@ -326,8 +321,6 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
static int bcm_kona_wdt_remove(struct platform_device *pdev)
{
bcm_kona_wdt_debug_exit(pdev);
bcm_kona_wdt_shutdown(pdev);
watchdog_unregister_device(&bcm_kona_wdt_wdd);
dev_dbg(&pdev->dev, "Watchdog driver disabled");
return 0;
@@ -346,7 +339,6 @@ static struct platform_driver bcm_kona_wdt_driver = {
},
.probe = bcm_kona_wdt_probe,
.remove = bcm_kona_wdt_remove,
.shutdown = bcm_kona_wdt_shutdown,
};
module_platform_driver(bcm_kona_wdt_driver);

View File

@@ -0,0 +1,290 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2018 ROHM Semiconductors
// ROHM BD70528MWV watchdog driver
#include <linux/bcd.h>
#include <linux/kernel.h>
#include <linux/mfd/rohm-bd70528.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/watchdog.h>
/*
* Max time we can set is 1 hour, 59 minutes and 59 seconds
* and Minimum time is 1 second
*/
#define WDT_MAX_MS ((2 * 60 * 60 - 1) * 1000)
#define WDT_MIN_MS 1000
#define DEFAULT_TIMEOUT 60
#define WD_CTRL_MAGIC1 0x55
#define WD_CTRL_MAGIC2 0xAA
struct wdtbd70528 {
struct device *dev;
struct regmap *regmap;
struct rohm_regmap_dev *mfd;
struct watchdog_device wdt;
};
/**
* bd70528_wdt_set - arm or disarm watchdog timer
*
* @data: device data for the PMIC instance we want to operate on
* @enable: new state of WDT. zero to disable, non zero to enable
* @old_state: previous state of WDT will be filled here
*
* Arm or disarm WDT on BD70528 PMIC. Expected to be called only by
* BD70528 RTC and BD70528 WDT drivers. The rtc_timer_lock must be taken
* by calling bd70528_wdt_lock before calling bd70528_wdt_set.
*/
int bd70528_wdt_set(struct rohm_regmap_dev *data, int enable, int *old_state)
{
int ret, i;
unsigned int tmp;
struct bd70528_data *bd70528 = container_of(data, struct bd70528_data,
chip);
u8 wd_ctrl_arr[3] = { WD_CTRL_MAGIC1, WD_CTRL_MAGIC2, 0 };
u8 *wd_ctrl = &wd_ctrl_arr[2];
ret = regmap_read(bd70528->chip.regmap, BD70528_REG_WDT_CTRL, &tmp);
if (ret)
return ret;
*wd_ctrl = (u8)tmp;
if (old_state) {
if (*wd_ctrl & BD70528_MASK_WDT_EN)
*old_state |= BD70528_WDT_STATE_BIT;
else
*old_state &= ~BD70528_WDT_STATE_BIT;
if ((!enable) == (!(*old_state & BD70528_WDT_STATE_BIT)))
return 0;
}
if (enable) {
if (*wd_ctrl & BD70528_MASK_WDT_EN)
return 0;
*wd_ctrl |= BD70528_MASK_WDT_EN;
} else {
if (*wd_ctrl & BD70528_MASK_WDT_EN)
*wd_ctrl &= ~BD70528_MASK_WDT_EN;
else
return 0;
}
for (i = 0; i < 3; i++) {
ret = regmap_write(bd70528->chip.regmap, BD70528_REG_WDT_CTRL,
wd_ctrl_arr[i]);
if (ret)
return ret;
}
ret = regmap_read(bd70528->chip.regmap, BD70528_REG_WDT_CTRL, &tmp);
if ((tmp & BD70528_MASK_WDT_EN) != (*wd_ctrl & BD70528_MASK_WDT_EN)) {
dev_err(bd70528->chip.dev,
"Watchdog ctrl mismatch (hw) 0x%x (set) 0x%x\n",
tmp, *wd_ctrl);
ret = -EIO;
}
return ret;
}
EXPORT_SYMBOL(bd70528_wdt_set);
/**
* bd70528_wdt_lock - take WDT lock
*
* @bd70528: device data for the PMIC instance we want to operate on
*
* Lock WDT for arming/disarming in order to avoid race condition caused
* by WDT state changes initiated by WDT and RTC drivers.
*/
void bd70528_wdt_lock(struct rohm_regmap_dev *data)
{
struct bd70528_data *bd70528 = container_of(data, struct bd70528_data,
chip);
mutex_lock(&bd70528->rtc_timer_lock);
}
EXPORT_SYMBOL(bd70528_wdt_lock);
/**
* bd70528_wdt_unlock - unlock WDT lock
*
* @bd70528: device data for the PMIC instance we want to operate on
*
* Unlock WDT lock which has previously been taken by call to
* bd70528_wdt_lock.
*/
void bd70528_wdt_unlock(struct rohm_regmap_dev *data)
{
struct bd70528_data *bd70528 = container_of(data, struct bd70528_data,
chip);
mutex_unlock(&bd70528->rtc_timer_lock);
}
EXPORT_SYMBOL(bd70528_wdt_unlock);
static int bd70528_wdt_set_locked(struct wdtbd70528 *w, int enable)
{
return bd70528_wdt_set(w->mfd, enable, NULL);
}
static int bd70528_wdt_change(struct wdtbd70528 *w, int enable)
{
int ret;
bd70528_wdt_lock(w->mfd);
ret = bd70528_wdt_set_locked(w, enable);
bd70528_wdt_unlock(w->mfd);
return ret;
}
static int bd70528_wdt_start(struct watchdog_device *wdt)
{
struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
dev_dbg(w->dev, "WDT ping...\n");
return bd70528_wdt_change(w, 1);
}
static int bd70528_wdt_stop(struct watchdog_device *wdt)
{
struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
dev_dbg(w->dev, "WDT stopping...\n");
return bd70528_wdt_change(w, 0);
}
static int bd70528_wdt_set_timeout(struct watchdog_device *wdt,
unsigned int timeout)
{
unsigned int hours;
unsigned int minutes;
unsigned int seconds;
int ret;
struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
seconds = timeout;
hours = timeout / (60 * 60);
/* Maximum timeout is 1h 59m 59s => hours is 1 or 0 */
if (hours)
seconds -= (60 * 60);
minutes = seconds / 60;
seconds = seconds % 60;
bd70528_wdt_lock(w->mfd);
ret = bd70528_wdt_set_locked(w, 0);
if (ret)
goto out_unlock;
ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_HOUR,
BD70528_MASK_WDT_HOUR, hours);
if (ret) {
dev_err(w->dev, "Failed to set WDT hours\n");
goto out_en_unlock;
}
ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_MINUTE,
BD70528_MASK_WDT_MINUTE, bin2bcd(minutes));
if (ret) {
dev_err(w->dev, "Failed to set WDT minutes\n");
goto out_en_unlock;
}
ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_SEC,
BD70528_MASK_WDT_SEC, bin2bcd(seconds));
if (ret)
dev_err(w->dev, "Failed to set WDT seconds\n");
else
dev_dbg(w->dev, "WDT tmo set to %u\n", timeout);
out_en_unlock:
ret = bd70528_wdt_set_locked(w, 1);
out_unlock:
bd70528_wdt_unlock(w->mfd);
return ret;
}
static const struct watchdog_info bd70528_wdt_info = {
.identity = "bd70528-wdt",
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
};
static const struct watchdog_ops bd70528_wdt_ops = {
.start = bd70528_wdt_start,
.stop = bd70528_wdt_stop,
.set_timeout = bd70528_wdt_set_timeout,
};
static int bd70528_wdt_probe(struct platform_device *pdev)
{
struct rohm_regmap_dev *bd70528;
struct wdtbd70528 *w;
int ret;
unsigned int reg;
bd70528 = dev_get_drvdata(pdev->dev.parent);
if (!bd70528) {
dev_err(&pdev->dev, "No MFD driver data\n");
return -EINVAL;
}
w = devm_kzalloc(&pdev->dev, sizeof(*w), GFP_KERNEL);
if (!w)
return -ENOMEM;
w->regmap = bd70528->regmap;
w->mfd = bd70528;
w->dev = &pdev->dev;
w->wdt.info = &bd70528_wdt_info;
w->wdt.ops = &bd70528_wdt_ops;
w->wdt.min_hw_heartbeat_ms = WDT_MIN_MS;
w->wdt.max_hw_heartbeat_ms = WDT_MAX_MS;
w->wdt.parent = pdev->dev.parent;
w->wdt.timeout = DEFAULT_TIMEOUT;
watchdog_set_drvdata(&w->wdt, w);
watchdog_init_timeout(&w->wdt, 0, pdev->dev.parent);
ret = bd70528_wdt_set_timeout(&w->wdt, w->wdt.timeout);
if (ret) {
dev_err(&pdev->dev, "Failed to set the watchdog timeout\n");
return ret;
}
bd70528_wdt_lock(w->mfd);
ret = regmap_read(w->regmap, BD70528_REG_WDT_CTRL, &reg);
bd70528_wdt_unlock(w->mfd);
if (ret) {
dev_err(&pdev->dev, "Failed to get the watchdog state\n");
return ret;
}
if (reg & BD70528_MASK_WDT_EN) {
dev_dbg(&pdev->dev, "watchdog was running during probe\n");
set_bit(WDOG_HW_RUNNING, &w->wdt.status);
}
ret = devm_watchdog_register_device(&pdev->dev, &w->wdt);
if (ret < 0)
dev_err(&pdev->dev, "watchdog registration failed: %d\n", ret);
return ret;
}
static struct platform_driver bd70528_wdt = {
.driver = {
.name = "bd70528-wdt"
},
.probe = bd70528_wdt_probe,
};
module_platform_driver(bd70528_wdt);
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
MODULE_DESCRIPTION("BD70528 watchdog driver");
MODULE_LICENSE("GPL");

View File

@@ -274,6 +274,11 @@ static const struct watchdog_ops cdns_wdt_ops = {
.set_timeout = cdns_wdt_settimeout,
};
static void cdns_clk_disable_unprepare(void *data)
{
clk_disable_unprepare(data);
}
/************************Platform Operations*****************************/
/**
* cdns_wdt_probe - Probe call for the device.
@@ -285,13 +290,13 @@ static const struct watchdog_ops cdns_wdt_ops = {
*/
static int cdns_wdt_probe(struct platform_device *pdev)
{
struct resource *res;
struct device *dev = &pdev->dev;
int ret, irq;
unsigned long clock_f;
struct cdns_wdt *wdt;
struct watchdog_device *cdns_wdt_device;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -302,19 +307,18 @@ static int cdns_wdt_probe(struct platform_device *pdev)
cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT;
cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
wdt->regs = devm_ioremap_resource(&pdev->dev, res);
wdt->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(wdt->regs))
return PTR_ERR(wdt->regs);
/* Register the interrupt */
wdt->rst = of_property_read_bool(pdev->dev.of_node, "reset-on-timeout");
wdt->rst = of_property_read_bool(dev->of_node, "reset-on-timeout");
irq = platform_get_irq(pdev, 0);
if (!wdt->rst && irq >= 0) {
ret = devm_request_irq(&pdev->dev, irq, cdns_wdt_irq_handler, 0,
ret = devm_request_irq(dev, irq, cdns_wdt_irq_handler, 0,
pdev->name, pdev);
if (ret) {
dev_err(&pdev->dev,
dev_err(dev,
"cannot register interrupt handler err=%d\n",
ret);
return ret;
@@ -322,30 +326,28 @@ static int cdns_wdt_probe(struct platform_device *pdev)
}
/* Initialize the members of cdns_wdt structure */
cdns_wdt_device->parent = &pdev->dev;
ret = watchdog_init_timeout(cdns_wdt_device, wdt_timeout, &pdev->dev);
if (ret) {
dev_err(&pdev->dev, "unable to set timeout value\n");
return ret;
}
cdns_wdt_device->parent = dev;
watchdog_init_timeout(cdns_wdt_device, wdt_timeout, dev);
watchdog_set_nowayout(cdns_wdt_device, nowayout);
watchdog_stop_on_reboot(cdns_wdt_device);
watchdog_set_drvdata(cdns_wdt_device, wdt);
wdt->clk = devm_clk_get(&pdev->dev, NULL);
wdt->clk = devm_clk_get(dev, NULL);
if (IS_ERR(wdt->clk)) {
dev_err(&pdev->dev, "input clock not found\n");
ret = PTR_ERR(wdt->clk);
return ret;
dev_err(dev, "input clock not found\n");
return PTR_ERR(wdt->clk);
}
ret = clk_prepare_enable(wdt->clk);
if (ret) {
dev_err(&pdev->dev, "unable to enable clock\n");
dev_err(dev, "unable to enable clock\n");
return ret;
}
ret = devm_add_action_or_reset(dev, cdns_clk_disable_unprepare,
wdt->clk);
if (ret)
return ret;
clock_f = clk_get_rate(wdt->clk);
if (clock_f <= CDNS_WDT_CLK_75MHZ) {
@@ -358,56 +360,20 @@ static int cdns_wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->io_lock);
ret = watchdog_register_device(cdns_wdt_device);
watchdog_stop_on_reboot(cdns_wdt_device);
watchdog_stop_on_unregister(cdns_wdt_device);
ret = devm_watchdog_register_device(dev, cdns_wdt_device);
if (ret) {
dev_err(&pdev->dev, "Failed to register wdt device\n");
goto err_clk_disable;
dev_err(dev, "Failed to register wdt device\n");
return ret;
}
platform_set_drvdata(pdev, wdt);
dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
wdt->regs, cdns_wdt_device->timeout,
nowayout ? ", nowayout" : "");
return 0;
err_clk_disable:
clk_disable_unprepare(wdt->clk);
return ret;
}
/**
* cdns_wdt_remove - Probe call for the device.
*
* @pdev: handle to the platform device structure.
* Return: 0 on success, otherwise negative error.
*
* Unregister the device after releasing the resources.
*/
static int cdns_wdt_remove(struct platform_device *pdev)
{
struct cdns_wdt *wdt = platform_get_drvdata(pdev);
cdns_wdt_stop(&wdt->cdns_wdt_device);
watchdog_unregister_device(&wdt->cdns_wdt_device);
clk_disable_unprepare(wdt->clk);
return 0;
}
/**
* cdns_wdt_shutdown - Stop the device.
*
* @pdev: handle to the platform structure.
*
*/
static void cdns_wdt_shutdown(struct platform_device *pdev)
{
struct cdns_wdt *wdt = platform_get_drvdata(pdev);
cdns_wdt_stop(&wdt->cdns_wdt_device);
clk_disable_unprepare(wdt->clk);
}
/**
@@ -462,8 +428,6 @@ MODULE_DEVICE_TABLE(of, cdns_wdt_of_match);
/* Driver Structure */
static struct platform_driver cdns_wdt_driver = {
.probe = cdns_wdt_probe,
.remove = cdns_wdt_remove,
.shutdown = cdns_wdt_shutdown,
.driver = {
.name = "cdns-wdt",
.of_match_table = cdns_wdt_of_match,

View File

@@ -6,7 +6,7 @@
* Watchdog driver for the ST-Ericsson AB COH 901 327 IP core
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/mod_devicetable.h>
#include <linux/types.h>
#include <linux/watchdog.h>
@@ -243,27 +243,15 @@ static struct watchdog_device coh901327_wdt = {
.timeout = U300_WDOG_DEFAULT_TIMEOUT,
};
static int __exit coh901327_remove(struct platform_device *pdev)
{
watchdog_unregister_device(&coh901327_wdt);
coh901327_disable();
free_irq(irq, pdev);
clk_disable_unprepare(clk);
clk_put(clk);
return 0;
}
static int __init coh901327_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int ret;
u16 val;
struct resource *res;
parent = dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
virtbase = devm_ioremap_resource(dev, res);
virtbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(virtbase))
return PTR_ERR(virtbase);
@@ -408,19 +396,13 @@ static struct platform_driver coh901327_driver = {
.driver = {
.name = "coh901327_wdog",
.of_match_table = coh901327_dt_match,
.suppress_bind_attrs = true,
},
.remove = __exit_p(coh901327_remove),
.suspend = coh901327_suspend,
.resume = coh901327_resume,
};
builtin_platform_driver_probe(coh901327_driver, coh901327_probe);
module_platform_driver_probe(coh901327_driver, coh901327_probe);
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("COH 901 327 Watchdog");
/* not really modular, but ... */
module_param(margin, uint, 0);
MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:coh901327-watchdog");

View File

@@ -150,13 +150,13 @@ static const struct watchdog_ops da9052_wdt_ops = {
static int da9052_wdt_probe(struct platform_device *pdev)
{
struct da9052 *da9052 = dev_get_drvdata(pdev->dev.parent);
struct device *dev = &pdev->dev;
struct da9052 *da9052 = dev_get_drvdata(dev->parent);
struct da9052_wdt_data *driver_data;
struct watchdog_device *da9052_wdt;
int ret;
driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data),
GFP_KERNEL);
driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
if (!driver_data)
return -ENOMEM;
driver_data->da9052 = da9052;
@@ -166,18 +166,17 @@ static int da9052_wdt_probe(struct platform_device *pdev)
da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
da9052_wdt->info = &da9052_wdt_info;
da9052_wdt->ops = &da9052_wdt_ops;
da9052_wdt->parent = &pdev->dev;
da9052_wdt->parent = dev;
watchdog_set_drvdata(da9052_wdt, driver_data);
ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG,
DA9052_CONTROLD_TWDSCALE, 0);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to disable watchdog bits, %d\n",
ret);
dev_err(dev, "Failed to disable watchdog bits, %d\n", ret);
return ret;
}
ret = devm_watchdog_register_device(&pdev->dev, &driver_data->wdt);
ret = devm_watchdog_register_device(dev, &driver_data->wdt);
if (ret != 0) {
dev_err(da9052->dev, "watchdog_register_device() failed: %d\n",
ret);

View File

@@ -119,13 +119,13 @@ static const struct watchdog_ops da9055_wdt_ops = {
static int da9055_wdt_probe(struct platform_device *pdev)
{
struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
struct device *dev = &pdev->dev;
struct da9055 *da9055 = dev_get_drvdata(dev->parent);
struct da9055_wdt_data *driver_data;
struct watchdog_device *da9055_wdt;
int ret;
driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data),
GFP_KERNEL);
driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
if (!driver_data)
return -ENOMEM;
@@ -136,17 +136,17 @@ static int da9055_wdt_probe(struct platform_device *pdev)
da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
da9055_wdt->info = &da9055_wdt_info;
da9055_wdt->ops = &da9055_wdt_ops;
da9055_wdt->parent = &pdev->dev;
da9055_wdt->parent = dev;
watchdog_set_nowayout(da9055_wdt, nowayout);
watchdog_set_drvdata(da9055_wdt, driver_data);
ret = da9055_wdt_stop(da9055_wdt);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to stop watchdog, %d\n", ret);
dev_err(dev, "Failed to stop watchdog, %d\n", ret);
return ret;
}
ret = devm_watchdog_register_device(&pdev->dev, &driver_data->wdt);
ret = devm_watchdog_register_device(dev, &driver_data->wdt);
if (ret != 0)
dev_err(da9055->dev, "watchdog_register_device() failed: %d\n",
ret);

View File

@@ -46,14 +46,9 @@ static unsigned int da9062_wdt_timeout_to_sel(unsigned int secs)
static int da9062_reset_watchdog_timer(struct da9062_watchdog *wdt)
{
int ret;
ret = regmap_update_bits(wdt->hw->regmap,
DA9062AA_CONTROL_F,
DA9062AA_WATCHDOG_MASK,
DA9062AA_WATCHDOG_MASK);
return ret;
return regmap_update_bits(wdt->hw->regmap, DA9062AA_CONTROL_F,
DA9062AA_WATCHDOG_MASK,
DA9062AA_WATCHDOG_MASK);
}
static int da9062_wdt_update_timeout_register(struct da9062_watchdog *wdt,
@@ -190,15 +185,16 @@ MODULE_DEVICE_TABLE(of, da9062_compatible_id_table);
static int da9062_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int ret;
struct da9062 *chip;
struct da9062_watchdog *wdt;
chip = dev_get_drvdata(pdev->dev.parent);
chip = dev_get_drvdata(dev->parent);
if (!chip)
return -EINVAL;
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
@@ -211,13 +207,13 @@ static int da9062_wdt_probe(struct platform_device *pdev)
wdt->wdtdev.min_hw_heartbeat_ms = DA9062_RESET_PROTECTION_MS;
wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
wdt->wdtdev.parent = &pdev->dev;
wdt->wdtdev.parent = dev;
watchdog_set_restart_priority(&wdt->wdtdev, 128);
watchdog_set_drvdata(&wdt->wdtdev, wdt);
ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev);
ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
if (ret < 0) {
dev_err(wdt->hw->dev,
"watchdog registration failed (%d)\n", ret);

Some files were not shown because too many files have changed in this diff Show More