Skip to content

Commit

Permalink
watchdog: jz4740: Use regmap provided by TCU driver
Browse files Browse the repository at this point in the history
Since we broke the ABI by changing the clock, the driver was also
updated to use the regmap provided by the TCU driver.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Tested-by: Mathieu Malaterre <malat@debian.org>
Tested-by: Artur Rojek <contact@artur-rojek.eu>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20191023174714.14362-2-paul@crapouillou.net
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
  • Loading branch information
Paul Cercueil authored and Wim Van Sebroeck committed Nov 18, 2019
1 parent 1d9c307 commit 6d53214
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
1 change: 1 addition & 0 deletions drivers/watchdog/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1645,6 +1645,7 @@ config JZ4740_WDT
depends on MACH_JZ4740 || MACH_JZ4780
depends on COMMON_CLK
select WATCHDOG_CORE
select MFD_SYSCON
help
Hardware driver for the built-in watchdog timer on Ingenic jz4740 SoCs.

Expand Down
35 changes: 20 additions & 15 deletions drivers/watchdog/jz4740_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

#include <linux/mfd/ingenic-tcu.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
Expand All @@ -17,6 +18,7 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/regmap.h>

#define DEFAULT_HEARTBEAT 5
#define MAX_HEARTBEAT 2048
Expand All @@ -36,7 +38,7 @@ MODULE_PARM_DESC(heartbeat,

struct jz4740_wdt_drvdata {
struct watchdog_device wdt;
void __iomem *base;
struct regmap *map;
struct clk *clk;
unsigned long clk_rate;
};
Expand All @@ -45,7 +47,8 @@ static int jz4740_wdt_ping(struct watchdog_device *wdt_dev)
{
struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);

writew(0x0, drvdata->base + TCU_REG_WDT_TCNT);
regmap_write(drvdata->map, TCU_REG_WDT_TCNT, 0);

return 0;
}

Expand All @@ -54,16 +57,16 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
{
struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
u16 timeout_value = (u16)(drvdata->clk_rate * new_timeout);
u8 tcer;
unsigned int tcer;

tcer = readb(drvdata->base + TCU_REG_WDT_TCER);
writeb(0x0, drvdata->base + TCU_REG_WDT_TCER);
regmap_read(drvdata->map, TCU_REG_WDT_TCER, &tcer);
regmap_write(drvdata->map, TCU_REG_WDT_TCER, 0);

writew((u16)timeout_value, drvdata->base + TCU_REG_WDT_TDR);
writew(0x0, drvdata->base + TCU_REG_WDT_TCNT);
regmap_write(drvdata->map, TCU_REG_WDT_TDR, timeout_value);
regmap_write(drvdata->map, TCU_REG_WDT_TCNT, 0);

if (tcer & TCU_WDT_TCER_TCEN)
writeb(TCU_WDT_TCER_TCEN, drvdata->base + TCU_REG_WDT_TCER);
regmap_write(drvdata->map, TCU_REG_WDT_TCER, TCU_WDT_TCER_TCEN);

wdt_dev->timeout = new_timeout;
return 0;
Expand All @@ -72,20 +75,20 @@ static int jz4740_wdt_set_timeout(struct watchdog_device *wdt_dev,
static int jz4740_wdt_start(struct watchdog_device *wdt_dev)
{
struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);
unsigned int tcer;
int ret;
u8 tcer;

ret = clk_prepare_enable(drvdata->clk);
if (ret)
return ret;

tcer = readb(drvdata->base + TCU_REG_WDT_TCER);
regmap_read(drvdata->map, TCU_REG_WDT_TCER, &tcer);

jz4740_wdt_set_timeout(wdt_dev, wdt_dev->timeout);

/* Start watchdog if it wasn't started already */
if (!(tcer & TCU_WDT_TCER_TCEN))
writeb(TCU_WDT_TCER_TCEN, drvdata->base + TCU_REG_WDT_TCER);
regmap_write(drvdata->map, TCU_REG_WDT_TCER, TCU_WDT_TCER_TCEN);

return 0;
}
Expand All @@ -94,7 +97,7 @@ static int jz4740_wdt_stop(struct watchdog_device *wdt_dev)
{
struct jz4740_wdt_drvdata *drvdata = watchdog_get_drvdata(wdt_dev);

writeb(0x0, drvdata->base + TCU_REG_WDT_TCER);
regmap_write(drvdata->map, TCU_REG_WDT_TCER, 0);
clk_disable_unprepare(drvdata->clk);

return 0;
Expand Down Expand Up @@ -172,9 +175,11 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(jz4740_wdt, nowayout);
watchdog_set_drvdata(jz4740_wdt, drvdata);

drvdata->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(drvdata->base))
return PTR_ERR(drvdata->base);
drvdata->map = device_node_to_regmap(dev->parent->of_node);
if (!drvdata->map) {
dev_err(dev, "regmap not found\n");
return -EINVAL;
}

return devm_watchdog_register_device(dev, &drvdata->wdt);
}
Expand Down

0 comments on commit 6d53214

Please sign in to comment.