summaryrefslogtreecommitdiff
path: root/drivers/watchdog/dw_wdt.c
AgeCommit message (Collapse)Author
2018-03-13watchdog: dw: save/restore control and timeout across suspend/resumeBrian Norris
Some platforms lose this state in suspend. It should be safe to do this unconditionally. Signed-off-by: Brian Norris <briannorris@chromium.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2018-03-13watchdog: dw: RMW the control registerBrian Norris
RK3399 has rst_pulse_length in CONTROL_REG[4:2], determining the length of pulse to issue for system reset. We shouldn't clobber this value, because that might make the system reset ineffective. On RK3399, we're seeing that a value of 000b (meaning 2 cycles) yields an unreliable (partial?) reset, and so we only fully reset after the watchdog fires a second time. If we retain the system default (010b, or 8 clock cycles), then the watchdog reset is much more reliable. Read-modify-write retains the system value and improves reset reliability. It seems we were intentionally clobbering the response mode previously, to ensure we performed a system reset (we don't support an interrupt notification), so retain that explicitly. Signed-off-by: Brian Norris <briannorris@chromium.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2017-12-28watchdog: dw_wdt: add stop watchdog operationOleksij Rempel
The only way of stopping the watchdog is by resetting it. Add the watchdog op for stopping the device and reset if a reset line is provided. At same time WDOG_HW_RUNNING should be remove from dw_wdt_start. As commented by Guenter Roeck: dw_wdt sets WDOG_HW_RUNNING in its open function. Result is that the kref_get() in watchdog_open() won't be executed. But then kref_put() in close will be called since the watchdog now does stop. This causes the imbalance. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Cc: Wim Van Sebroeck <wim@iguana.be> Cc: Guenter Roeck <linux@roeck-us.net> Cc: linux-watchdog@vger.kernel.org Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2017-07-03watchdog: dw_wdt: get reset lines from dtSteffen Trumtrar
The dw_wdt has an external reset line, that can keep the device in reset and therefore rendering it useless and also is the only way of stopping the watchdog once it was started. Get the reset lines for this core from the devicetree. As these lines are optional, use devm_reset_control_get_optional_shared. If the reset line is not specified in the devicetree, the reset framework will just skip deasserting and continue. This way all users of the driver will continue to function without any harm, even if the reset line is not specified in the devicetree. Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> Cc: linux-watchdog@vger.kernel.org Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2017-02-24watchdog: dw_wdt: Use watchdog core to install restart handlerGuenter Roeck
Use the infrastructure provided by the watchdog core to install the restart handler. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
2016-09-23watchdog: dw_wdt: Read clock rate only once and validate itGuenter Roeck
Coverity reports: divide_by_zero: In expression readl(dw_wdt->regs + 8) / clk_get_rate(dw_wdt->clk), division by expression clk_get_rate(dw_wdt->clk) which may be zero has undefined behavior. The clock used for the watchdog timer won't change its rate, so read it only once during probe. Also validate it and abort the probe function with an error if it is 0. Cc: Douglas Anderson <dianders@chromium.org> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2016-03-16watchdog: dw_wdt: Convert to use watchdog infrastructureGuenter Roeck
Convert driver to use watchdog infrastructure. This includes infrastructure support to handle watchdog keepalive if the watchdog is running while the watchdog device is closed. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2015-12-27watchdog: dw_wdt: fix signedness bug in dw_wdt_top_in_seconds()Jisheng Zhang
On 64bit platforms, "(1 << (16 + top)) / clk_get_rate(dw_wdt.clk)" is sign-extended to 64bit then converted to unsigned 64bit, finally divide the clk rate. If the top is the maximum TOP i.e 15, "(1 << (16 +15))" will be sign-extended to 0xffffffff80000000, then converted to unsigned 0xffffffff80000000, which is a huge number, thus the final result is wrong. We fix this issue by giving usigned value(1U in this case) at first. Let's assume clk rate is 25MHZ, Before the patch: dw_wdt_top_in_seconds(15) = -864612050 After the patch: dw_wdt_top_in_seconds(15) = 85 Signed-off-by: Jisheng Zhang <jszhang@marvell.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2015-06-22watchdog: dw_wdt: keepalive the watchdog at write timeDoug Anderson
If you've got code that does this in a tight loop 1. Open watchdog 2. Send 'expect close' 3. Close watchdog ...you'll eventually trigger a watchdog reset. You can reproduce this by using daisydog (1) and running: while true; do daisydog -c > /dev/null; done The problem is that each time you write to the watchdog for 'expect close' it moves the timer .5 seconds out. The timer thus never fires and never pats the watchdog for you. 1: http://git.chromium.org/gitweb/?p=chromiumos/third_party/daisydog.git Signed-off-by: Doug Anderson <dianders@chromium.org> Tested-by: Jisheng Zhang <jszhang@marvell.com> Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2015-06-22watchdog: dw_wdt: No need for a spinlockDoug Anderson
Right now the dw_wdt uses a spinlock to protect dw_wdt_open(). The problem is that while holding the spinlock we call: -> dw_wdt_set_top() -> dw_wdt_top_in_seconds() -> clk_get_rate() -> clk_prepare_lock() -> mutex_lock() Locking a mutex while holding a spinlock is not allowed and leads to warnings like "BUG: spinlock wrong CPU on CPU#1", among other problems. There's no reason to use a spinlock. Only dw_wdt_open() was protected and the test_and_set_bit() at the start of that function protects us anyway. Signed-off-by: Doug Anderson <dianders@chromium.org> Tested-by: Jisheng Zhang <jszhang@marvell.com> Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2015-02-17watchdog: dw_wdt: Try to get a 30 second watchdog by defaultDoug Anderson
The dw_wdt_set_top() function takes in a value in seconds. In dw_wdt_open() we were calling it with a value that's supposed to represent the maximum value programmed into the "top" register with a comment saying that we were trying to set the watchdog to its maximum value. Instead we ended up setting the watchdog to ~15 seconds. Let's fix this. However, setting things to the "max" gives me an 86 second watchdog in the system I'm looking at. 86 seconds feels a little too long. We'll explicitly choose 30 seconds as a more reasonable value. NOTE: Ideally this driver should be transitioned to be a real watchdog driver. Then we could use "watchdog_init_timeout" and let the timeout be specified in a number of ways (device tree, module parameter, etc). This patch should be considered a bit of a stopgap solution. Signed-off-by: Doug Anderson <dianders@chromium.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2015-02-17watchdog: dw_wdt: pat the watchdog before enabling itDoug Anderson
On some dw_wdt implementations the "top" register may be initted to 0 at bootup. In such a case, each "pat" of the watchdog will reset the timer to 0xffff. That's pretty short. The input clock of the wdt can be any of a wide range of values. On an rk3288 system, I've seen the wdt clock be 24.75 MHz. That means each tick is ~40ns and we'll count to 0xffff in ~2.6ms. Because of the above two facts, it's a really good idea to pat the watchdog after initting the "top" register properly and before enabling the watchdog. If you don't then there's no way we'll get the next heartbeat in time. Jisheng Zhang fixed this problem on some dw_wdt versions by using the TOP_INIT feature. However, the dw_wdt on rk3288 doesn't have TOP_INIT so it's a good idea to also pat the watchdog manually. Signed-off-by: Doug Anderson <dianders@chromium.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2014-11-03Merge branch 'platform/remove_owner' of ↵Greg Kroah-Hartman
git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux into driver-core-next Remove all .owner fields from platform drivers
2014-10-20watchdog: dw_wdt: add restart handler supportJisheng Zhang
The kernel core now provides an API to trigger a system restart. Register with it to support restarting the system via. watchdog. Signed-off-by: Jisheng Zhang <jszhang@marvell.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2014-10-20watchdog: dw_wdt: initialise TOP_INIT in dw_wdt_set_top()Jisheng Zhang
The TOP_INIT, ie bit 4-7 of the WDOG_TIMEOUT_RANGE_REG_OFFSET register may be zero, so the timeout period may be very short after initialization is done, thus the system may be reset soon after enabling. We fix this problem by also initialising the TOP_INIT when setting TOP in function dw_wdt_set_top(). Signed-off-by: Jisheng Zhang <jszhang@marvell.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2014-10-20watchdog: drop owner assignment from platform_driversWolfram Sang
A platform_driver does not need to set an owner, it will be populated by the driver core. Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
2014-08-05watchdog: dw_wdt: Remove the un-necessary check after platform_get_resource()George Cherian
devm_ioremap_resource() checks for valid resource. Remove the un-necessary check after platform_get_resource(). Signed-off-by: George Cherian <george.cherian@ti.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2014-01-28watchdog: dw_wdt: remove build dependenciesBaruch Siach
There is nothing ARM specific in this driver, and we intend to use it on the Xtensa architecture. Also, clk.h now includes stubs for !CONFIG_HAVE_CLK, so the driver should build anyway. Signed-off-by: Baruch Siach <baruch@tkos.co.il> Acked-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2013-11-17watchdog: dw: Enable OF support for DW watchdog timerDinh Nguyen
Add device tree support to the DW watchdog timer. Signed-off-by: Dinh Nguyen <dinguyen@altera.com> Acked-by: Jamie Iles <jamie@jamieiles.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Pavel Machek <pavel@denx.de> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be> Cc: Viresh Kumar <viresh.linux@gmail.com> Cc: Rob Herring <rob.herring@calxeda.com> Cc: Pawel Moll <pawel.moll@arm.com> Cc: Stephen Warren <swarren@wwwdotorg.org> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk> Cc: devicetree@vger.kernel.org Cc: linux-watchdog@vger.kernel.org
2013-11-17watchdog: Get rid of MODULE_ALIAS_MISCDEV statementsJean Delvare
I just can't find any value in MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) and MODULE_ALIAS_MISCDEV(TEMP_MINOR) statements. Either the device is enumerated and the driver already has a module alias (e.g. PCI, USB etc.) that will get the right driver loaded automatically. Or the device is not enumerated and loading its driver will lead to more or less intrusive hardware poking. Such hardware poking should be limited to a bare minimum, so the user should really decide which drivers should be tried and in what order. Trying them all in arbitrary order can't do any good. On top of that, loading that many drivers at once bloats the kernel log. Also many drivers will stay loaded afterward, bloating the output of "lsmod" and wasting memory. Some modules (cs5535_mfgpt which gets loaded as a dependency) can't even be unloaded! If defining char-major-10-130 is needed then it should happen in user-space. Signed-off-by: Jean Delvare <jdelvare@suse.de> Acked-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be> Cc: Stephen Warren <swarren@wwwdotorg.org> Cc: Mike Frysinger <vapier.adi@gmail.com> Cc: Wan ZongShun <mcuos.com@gmail.com> Cc: Ben Dooks <ben-linux@fluff.org> Cc: Kukjin Kim <kgene.kim@samsung.com> Cc: Zwane Mwaikambo <zwane@arm.linux.org.uk> Cc: Jim Cromie <jim.cromie@gmail.com>
2013-11-17watchdog: dw_wdt: Add __user annotationJingoo Han
Added __user annotation to fix the following sparse warnings. drivers/watchdog/dw_wdt.c:206:38: warning: incorrect type in argument 1 (different address spaces) drivers/watchdog/dw_wdt.c:206:38: expected void [noderef] <asn:1>*to drivers/watchdog/dw_wdt.c:206:38: got struct watchdog_info *<noident> drivers/watchdog/dw_wdt.c:211:24: warning: incorrect type in initializer (different address spaces) drivers/watchdog/dw_wdt.c:211:24: expected int const [noderef] <asn:1>*register __p drivers/watchdog/dw_wdt.c:211:24: got int *<noident> Signed-off-by: Jingoo Han <jg1.han@samsung.com> Acked-by: Jamie Iles <jamie@jamieiles.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2013-11-17watchdog: dw_wdt: use clk_prepare_enable and clk_disable_unprepareHeiko Stübner
This is necessary to make the driver work with platforms using the common clock framework. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2013-11-17watchdog: dw_wdt: convert to SIMPLE_DEV_PM_OPSHeiko Stübner
The dw_wdt only provides PM_SLEEP operations, so convert the driver to use SIMPLE_DEV_PM_OPS instead of populating the struct manually. This has the added effect of simplifying the CONFIG_PM ifdefs. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2013-07-11watchdog: dw_wdt: Staticize local symbolSachin Kamat
'dw_wdt_write' is used only in this file. Make it static. Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2013-07-11watchdog: dw_wdt: use devm_clk_get()Jingoo Han
Use devm_clk_get() to make cleanup paths more simple. Signed-off-by: Jingoo Han <jg1.han@samsung.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2013-01-25watchdog: Convert to devm_ioremap_resource()Thierry Reding
Convert all uses of devm_request_and_ioremap() to the newly introduced devm_ioremap_resource() which provides more consistent error handling. devm_ioremap_resource() provides its own error messages so all explicit error messages can be removed from the failure code paths. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Cc: Wim Van Sebroeck <wim@iguana.be> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-28watchdog: remove use of __devexitBill Pemberton
CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton <wfp5p@virginia.edu> Cc: Wim Van Sebroeck <wim@iguana.be> Cc: Wan ZongShun <mcuos.com@gmail.com> Cc: Ben Dooks <ben-linux@fluff.org> Cc: Kukjin Kim <kgene.kim@samsung.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-28watchdog: remove use of __devinitBill Pemberton
CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton <wfp5p@virginia.edu> Cc: Wim Van Sebroeck <wim@iguana.be> Cc: Wan ZongShun <mcuos.com@gmail.com> Cc: Ben Dooks <ben-linux@fluff.org> Cc: Kukjin Kim <kgene.kim@samsung.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-11-28watchdog: remove use of __devexit_pBill Pemberton
CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton <wfp5p@virginia.edu> Cc: Wim Van Sebroeck <wim@iguana.be> Cc: Wan ZongShun <mcuos.com@gmail.com> Cc: Ben Dooks <ben-linux@fluff.org> Cc: Kukjin Kim <kgene.kim@samsung.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2012-03-27watchdog: nowayout is boolWim Van Sebroeck
nowayout is actually a boolean value. So make it bool for all watchdog device drivers. Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2012-03-27watchdog: Use pr_<fmt> and pr_<level>Joe Perches
Use the current logging styles. Make sure all output has a prefix. Add missing newlines. Remove now unnecessary PFX, NAME, and miscellaneous other #defines. Coalesce formats. Signed-off-by: Joe Perches <joe@perches.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2012-01-27watchdog: dw_wdt.c: use devm_request_and_ioremapJulia Lawall
Reimplement a call to devm_request_mem_region followed by a call to ioremap or ioremap_nocache by a call to devm_request_and_ioremap. The semantic patch that makes this transformation is as follows: (http://coccinelle.lip6.fr/) // <smpl> @nm@ expression myname; identifier i; @@ struct platform_driver i = { .driver = { .name = myname } }; @@ expression dev,res,size; expression nm.myname; @@ -if (!devm_request_mem_region(dev, res->start, size, - \(res->name\|dev_name(dev)\|myname\))) { - ... - return ...; -} ... when != res->start ( -devm_ioremap(dev,res->start,size) +devm_request_and_ioremap(dev,res) | -devm_ioremap_nocache(dev,res->start,size) +devm_request_and_ioremap(dev,res) ) ... when any when != res->start // </smpl> Signed-off-by: Julia Lawall <julia@diku.dk> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2012-01-06watchdog: convert drivers/watchdog/* to use module_platform_driver()Axel Lin
This patch converts the drivers in drivers/watchdog/* to use the module_platform_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin <axel.lin@gmail.com> Cc: Nicolas Thill <nico@openwrt.org> Cc: Florian Fainelli <florian@openwrt.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Paul Cercueil <paul@crapouillou.net> Cc: Marc Zyngier <maz@misterjones.org> Cc: Wan ZongShun <mcuos.com@gmail.com> Cc: Alejandro Cabrera <aldaya@gmail.com> Cc: "George G. Davis" <gdavis@mvista.com> Cc: Sylver Bruneau <sylver.bruneau@googlemail.com> Cc: Vitaly Wool <vital@embeddedalley.com> Cc: Mika Westerberg <mika.westerberg@iki.fi> Cc: Timo Kokkonen <timo.t.kokkonen@nokia.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
2011-07-22watchdog: add support for the Synopsys DesignWare WDTJamie Iles
The Synopsys DesignWare watchdog is found in several ARM based systems and provides a choice of 16 timeout periods depending on the clock input. The watchdog cannot be disabled once started. Signed-off-by: Jamie Iles <jamie@jamieiles.com> Acked-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>