2009-11-29 17:58:38 +03:00
/*
* Watchdog driver for Technologic Systems TS - 72 xx based SBCs
* ( TS - 7200 , TS - 7250 and TS - 7260 ) . These boards have external
* glue logic CPLD chip , which includes programmable watchdog
* timer .
*
* Copyright ( c ) 2009 Mika Westerberg < mika . westerberg @ iki . fi >
*
* This driver is based on ep93xx_wdt and wm831x_wdt drivers .
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed " as is " without any
* warranty of any kind , whether express or implied .
*/
# include <linux/platform_device.h>
2017-01-31 19:33:30 +03:00
# include <linux/module.h>
2009-11-29 17:58:38 +03:00
# include <linux/watchdog.h>
2017-01-31 19:33:30 +03:00
# include <linux/io.h>
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
# define TS72XX_WDT_DEFAULT_TIMEOUT 30
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
static int timeout ;
2009-11-29 17:58:38 +03:00
module_param ( timeout , int , 0 ) ;
2017-01-31 19:33:30 +03:00
MODULE_PARM_DESC ( timeout , " Watchdog timeout in seconds. " ) ;
2009-11-29 17:58:38 +03:00
2012-03-05 19:51:11 +04:00
static bool nowayout = WATCHDOG_NOWAYOUT ;
module_param ( nowayout , bool , 0 ) ;
2009-11-29 17:58:38 +03:00
MODULE_PARM_DESC ( nowayout , " Disable watchdog shutdown on close " ) ;
2017-01-31 19:33:30 +03:00
/* priv->control_reg */
# define TS72XX_WDT_CTRL_DISABLE 0x00
# define TS72XX_WDT_CTRL_250MS 0x01
# define TS72XX_WDT_CTRL_500MS 0x02
# define TS72XX_WDT_CTRL_1SEC 0x03
# define TS72XX_WDT_CTRL_RESERVED 0x04
# define TS72XX_WDT_CTRL_2SEC 0x05
# define TS72XX_WDT_CTRL_4SEC 0x06
# define TS72XX_WDT_CTRL_8SEC 0x07
/* priv->feed_reg */
# define TS72XX_WDT_FEED_VAL 0x05
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
struct ts72xx_wdt_priv {
2009-11-29 17:58:38 +03:00
void __iomem * control_reg ;
void __iomem * feed_reg ;
2017-01-31 19:33:30 +03:00
struct watchdog_device wdd ;
unsigned char regval ;
2009-11-29 17:58:38 +03:00
} ;
2017-01-31 19:33:30 +03:00
static int ts72xx_wdt_start ( struct watchdog_device * wdd )
2009-11-29 17:58:38 +03:00
{
2017-01-31 19:33:30 +03:00
struct ts72xx_wdt_priv * priv = watchdog_get_drvdata ( wdd ) ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
writeb ( TS72XX_WDT_FEED_VAL , priv - > feed_reg ) ;
writeb ( priv - > regval , priv - > control_reg ) ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
return 0 ;
2009-11-29 17:58:38 +03:00
}
2017-01-31 19:33:30 +03:00
static int ts72xx_wdt_stop ( struct watchdog_device * wdd )
2009-11-29 17:58:38 +03:00
{
2017-01-31 19:33:30 +03:00
struct ts72xx_wdt_priv * priv = watchdog_get_drvdata ( wdd ) ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
writeb ( TS72XX_WDT_FEED_VAL , priv - > feed_reg ) ;
writeb ( TS72XX_WDT_CTRL_DISABLE , priv - > control_reg ) ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
return 0 ;
2009-11-29 17:58:38 +03:00
}
2017-01-31 19:33:30 +03:00
static int ts72xx_wdt_ping ( struct watchdog_device * wdd )
2009-11-29 17:58:38 +03:00
{
2017-01-31 19:33:30 +03:00
struct ts72xx_wdt_priv * priv = watchdog_get_drvdata ( wdd ) ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
writeb ( TS72XX_WDT_FEED_VAL , priv - > feed_reg ) ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
return 0 ;
2009-11-29 17:58:38 +03:00
}
2017-01-31 19:33:30 +03:00
static int ts72xx_wdt_settimeout ( struct watchdog_device * wdd , unsigned int to )
2009-11-29 17:58:38 +03:00
{
2017-01-31 19:33:30 +03:00
struct ts72xx_wdt_priv * priv = watchdog_get_drvdata ( wdd ) ;
if ( to = = 1 ) {
priv - > regval = TS72XX_WDT_CTRL_1SEC ;
} else if ( to = = 2 ) {
priv - > regval = TS72XX_WDT_CTRL_2SEC ;
} else if ( to < = 4 ) {
priv - > regval = TS72XX_WDT_CTRL_4SEC ;
to = 4 ;
2009-11-29 17:58:38 +03:00
} else {
2017-01-31 19:33:30 +03:00
priv - > regval = TS72XX_WDT_CTRL_8SEC ;
if ( to < = 8 )
to = 8 ;
2009-11-29 17:58:38 +03:00
}
2017-01-31 19:33:30 +03:00
wdd - > timeout = to ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
if ( watchdog_active ( wdd ) ) {
ts72xx_wdt_stop ( wdd ) ;
ts72xx_wdt_start ( wdd ) ;
2009-11-29 17:58:38 +03:00
}
2017-01-31 19:33:30 +03:00
return 0 ;
2009-11-29 17:58:38 +03:00
}
2017-01-31 19:33:30 +03:00
static const struct watchdog_info ts72xx_wdt_ident = {
. options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
2009-11-29 17:58:38 +03:00
WDIOF_MAGICCLOSE ,
. firmware_version = 1 ,
. identity = " TS-72XX WDT " ,
} ;
2017-07-08 03:18:40 +03:00
static const struct watchdog_ops ts72xx_wdt_ops = {
2009-11-29 17:58:38 +03:00
. owner = THIS_MODULE ,
2017-01-31 19:33:30 +03:00
. start = ts72xx_wdt_start ,
. stop = ts72xx_wdt_stop ,
. ping = ts72xx_wdt_ping ,
. set_timeout = ts72xx_wdt_settimeout ,
2009-11-29 17:58:38 +03:00
} ;
2012-11-19 22:21:41 +04:00
static int ts72xx_wdt_probe ( struct platform_device * pdev )
2009-11-29 17:58:38 +03:00
{
2019-04-10 19:27:45 +03:00
struct device * dev = & pdev - > dev ;
2017-01-31 19:33:30 +03:00
struct ts72xx_wdt_priv * priv ;
struct watchdog_device * wdd ;
int ret ;
2009-11-29 17:58:38 +03:00
2019-04-10 19:27:45 +03:00
priv = devm_kzalloc ( dev , sizeof ( * priv ) , GFP_KERNEL ) ;
2017-01-31 19:33:30 +03:00
if ( ! priv )
2009-11-29 17:58:38 +03:00
return - ENOMEM ;
watchdog: Convert to use devm_platform_ioremap_resource
Use devm_platform_ioremap_resource to reduce source code size,
improve readability, and reduce the likelyhood of bugs.
The conversion was done automatically with coccinelle using the
following semantic patch.
@r@
identifier res, pdev;
expression a;
expression index;
expression e;
@@
<+...
- res = platform_get_resource(pdev, IORESOURCE_MEM, index);
- a = devm_ioremap_resource(e, res);
+ a = devm_platform_ioremap_resource(pdev, index);
...+>
@depends on r@
identifier r.res;
@@
- struct resource *res;
... when != res
@@
identifier res, pdev;
expression index;
expression a;
@@
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, index);
- a = devm_ioremap_resource(&pdev->dev, res);
+ a = devm_platform_ioremap_resource(pdev, index);
Cc: Joel Stanley <joel@jms.id.au>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Keguang Zhang <keguang.zhang@gmail.com>
Cc: Vladimir Zapolskiy <vz@mleia.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Avi Fishman <avifishman70@gmail.com>
Cc: Nancy Yuen <yuenn@google.com>
Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Wan ZongShun <mcuos.com@gmail.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Sylvain Lemieux <slemieux.tyco@gmail.com>
Cc: Kukjin Kim <kgene@kernel.org>
Cc: Barry Song <baohua@kernel.org>
Cc: Orson Zhai <orsonzhai@gmail.com>
Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Maxime Ripard <maxime.ripard@bootlin.com>
Cc: Chen-Yu Tsai <wens@csie.org>
Cc: Marc Gonzalez <marc.w.gonzalez@free.fr>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Tested-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Acked-by: Michal Simek <michal.simek@xilinx.com> (cadence/xilinx wdts)
Acked-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
2019-04-02 22:01:53 +03:00
priv - > control_reg = devm_platform_ioremap_resource ( pdev , 0 ) ;
2017-01-31 19:33:30 +03:00
if ( IS_ERR ( priv - > control_reg ) )
return PTR_ERR ( priv - > control_reg ) ;
2009-11-29 17:58:38 +03:00
watchdog: Convert to use devm_platform_ioremap_resource
Use devm_platform_ioremap_resource to reduce source code size,
improve readability, and reduce the likelyhood of bugs.
The conversion was done automatically with coccinelle using the
following semantic patch.
@r@
identifier res, pdev;
expression a;
expression index;
expression e;
@@
<+...
- res = platform_get_resource(pdev, IORESOURCE_MEM, index);
- a = devm_ioremap_resource(e, res);
+ a = devm_platform_ioremap_resource(pdev, index);
...+>
@depends on r@
identifier r.res;
@@
- struct resource *res;
... when != res
@@
identifier res, pdev;
expression index;
expression a;
@@
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, index);
- a = devm_ioremap_resource(&pdev->dev, res);
+ a = devm_platform_ioremap_resource(pdev, index);
Cc: Joel Stanley <joel@jms.id.au>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Keguang Zhang <keguang.zhang@gmail.com>
Cc: Vladimir Zapolskiy <vz@mleia.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Avi Fishman <avifishman70@gmail.com>
Cc: Nancy Yuen <yuenn@google.com>
Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Wan ZongShun <mcuos.com@gmail.com>
Cc: Michal Simek <michal.simek@xilinx.com>
Cc: Sylvain Lemieux <slemieux.tyco@gmail.com>
Cc: Kukjin Kim <kgene@kernel.org>
Cc: Barry Song <baohua@kernel.org>
Cc: Orson Zhai <orsonzhai@gmail.com>
Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Maxime Ripard <maxime.ripard@bootlin.com>
Cc: Chen-Yu Tsai <wens@csie.org>
Cc: Marc Gonzalez <marc.w.gonzalez@free.fr>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Tested-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Acked-by: Michal Simek <michal.simek@xilinx.com> (cadence/xilinx wdts)
Acked-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Patrice Chotard <patrice.chotard@st.com>
Acked-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
2019-04-02 22:01:53 +03:00
priv - > feed_reg = devm_platform_ioremap_resource ( pdev , 1 ) ;
2017-01-31 19:33:30 +03:00
if ( IS_ERR ( priv - > feed_reg ) )
return PTR_ERR ( priv - > feed_reg ) ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
wdd = & priv - > wdd ;
wdd - > info = & ts72xx_wdt_ident ;
wdd - > ops = & ts72xx_wdt_ops ;
wdd - > min_timeout = 1 ;
wdd - > max_hw_heartbeat_ms = 8000 ;
2019-04-10 19:27:45 +03:00
wdd - > parent = dev ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
watchdog_set_nowayout ( wdd , nowayout ) ;
2010-08-29 14:53:14 +04:00
2017-01-31 19:33:30 +03:00
wdd - > timeout = TS72XX_WDT_DEFAULT_TIMEOUT ;
2019-04-10 19:27:45 +03:00
watchdog_init_timeout ( wdd , timeout , dev ) ;
2009-11-29 17:58:38 +03:00
2017-01-31 19:33:30 +03:00
watchdog_set_drvdata ( wdd , priv ) ;
2009-11-29 17:58:38 +03:00
2019-04-10 19:27:45 +03:00
ret = devm_watchdog_register_device ( dev , wdd ) ;
2017-01-31 19:33:30 +03:00
if ( ret )
return ret ;
2019-04-10 19:27:45 +03:00
dev_info ( dev , " TS-72xx Watchdog driver \n " ) ;
2009-11-29 17:58:38 +03:00
2015-07-31 01:59:57 +03:00
return 0 ;
2009-11-29 17:58:38 +03:00
}
static struct platform_driver ts72xx_wdt_driver = {
. probe = ts72xx_wdt_probe ,
. driver = {
. name = " ts72xx-wdt " ,
} ,
} ;
2011-11-29 09:56:27 +04:00
module_platform_driver ( ts72xx_wdt_driver ) ;
2009-11-29 17:58:38 +03:00
MODULE_AUTHOR ( " Mika Westerberg <mika.westerberg@iki.fi> " ) ;
MODULE_DESCRIPTION ( " TS-72xx SBC Watchdog " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " platform:ts72xx-wdt " ) ;