From 7ee9473d890737e88fc14acb17eef4b11ff68690 Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Mon, 27 Aug 2018 21:34:32 +1000 Subject: [PATCH] [WATCHDOG] Re-factor ts_wdt to use ts-mcu-core --- drivers/watchdog/Kconfig | 1 + drivers/watchdog/ts_wdt.c | 87 ++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 5feb1001d095..8fdf1658d0cc 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -545,6 +545,7 @@ config TS4800_WATCHDOG config TS_WDT_MICRO tristate "Technologic Microcontroller Watchdog" depends on ARM + select MFD_TS_MCU select WATCHDOG_CORE help Hardware driver for the Technologic Systems silabs based diff --git a/drivers/watchdog/ts_wdt.c b/drivers/watchdog/ts_wdt.c index 4a45185dd670..86569ce7def3 100644 --- a/drivers/watchdog/ts_wdt.c +++ b/drivers/watchdog/ts_wdt.c @@ -21,16 +21,18 @@ #include #include +#include + #define TS_DEFAULT_TIMEOUT 30 static bool nowayout = WATCHDOG_NOWAYOUT; struct ts_wdt_dev { - struct device *dev; + struct ts_mcu_dev *mcu; struct delayed_work ping_work; }; -struct i2c_client *client; +static struct ts_wdt_dev *wdev; /* The WDT expects 3 values: * 0 (always) @@ -55,53 +57,50 @@ static int ts_wdt_write(u16 deciseconds) out[0] = 0; out[1] = (deciseconds & 0xff00) >> 8; out[2] = deciseconds & 0xff; - dev_dbg(&client->dev, "Writing 0x00, 0x%02x, 0x%02x\n", + dev_dbg(wdev->mcu->dev, "Writing 0x00, 0x%02x, 0x%02x\n", out[1], out[2]); - msg.addr = client->addr; msg.flags = 0; msg.len = 3; msg.buf = out; - ret = i2c_transfer(client->adapter, &msg, 1); + ret = ts_mcu_transfer(wdev->mcu, &msg, 1); if (ret != 1) { - dev_err(&client->dev, "%s: write error, ret=%d\n", + dev_err(wdev->mcu->dev, "%s: write error, ret=%d\n", __func__, ret); } return !ret; } /* Watchdog is on by default. We feed every timeout/2 until userspace feeds */ -static void ts_wdt_ping_enable(struct ts_wdt_dev *wdev) +static void ts_wdt_ping_enable() { - dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(wdev->mcu->dev, "%s\n", __func__); ts_wdt_write(TS_DEFAULT_TIMEOUT * 10); schedule_delayed_work(&wdev->ping_work, round_jiffies_relative(TS_DEFAULT_TIMEOUT * HZ / 2)); } -static void ts_wdt_ping_disable(struct ts_wdt_dev *wdev) +static void ts_wdt_ping_disable() { - dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(wdev->mcu->dev, "%s\n", __func__); ts_wdt_write(TS_DEFAULT_TIMEOUT * 10); cancel_delayed_work_sync(&wdev->ping_work); } static int ts_wdt_start(struct watchdog_device *wdt) { - struct ts_wdt_dev *wdev = watchdog_get_drvdata(wdt); + dev_dbg(wdev->mcu->dev, "%s\n", __func__); + dev_dbg(wdev->mcu->dev, "Feeding for %d seconds\n", wdt->timeout); - dev_dbg(&client->dev, "%s\n", __func__); - dev_dbg(&client->dev, "Feeding for %d seconds\n", wdt->timeout); - - ts_wdt_ping_disable(wdev); + ts_wdt_ping_disable(); return ts_wdt_write(wdt->timeout * 10); } static int ts_wdt_stop(struct watchdog_device *wdt) { - dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(wdev->mcu->dev, "%s\n", __func__); return ts_wdt_write(3); } @@ -110,7 +109,7 @@ static void do_ts_reboot(enum reboot_mode reboot_mode, const char *cmd) unsigned long flags; static DEFINE_SPINLOCK(wdt_lock); - dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(wdev->mcu->dev, "%s\n", __func__); spin_lock_irqsave(&wdt_lock, flags); ts_wdt_write(0); @@ -122,7 +121,7 @@ static void do_ts_halt(void) unsigned long flags; static DEFINE_SPINLOCK(wdt_lock); - dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(wdev->mcu->dev, "%s\n", __func__); spin_lock_irqsave(&wdt_lock, flags); ts_wdt_write(3); @@ -132,17 +131,15 @@ static void do_ts_halt(void) static int ts_set_timeout(struct watchdog_device *wdt, unsigned int timeout) { - dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(wdev->mcu->dev, "%s\n", __func__); wdt->timeout = timeout; return 0; } static void ts_wdt_ping_work(struct work_struct *work) { - struct ts_wdt_dev *wdev = container_of(to_delayed_work(work), - struct ts_wdt_dev, ping_work); - dev_dbg(&client->dev, "%s\n", __func__); - ts_wdt_ping_enable(wdev); + dev_dbg(wdev->mcu->dev, "%s\n", __func__); + ts_wdt_ping_enable(); } static struct watchdog_info ts_wdt_ident = { @@ -166,20 +163,24 @@ static struct watchdog_device ts_wdt_wdd = { .max_timeout = 6553, }; -static int tsreboot_probe(struct i2c_client *c, - const struct i2c_device_id *id) +static int ts_wdt_probe(struct platform_device *pdev) { int err; - struct ts_wdt_dev *wdev; - client = c; + struct ts_mcu_dev *mcu = dev_get_drvdata(pdev->dev.parent); - wdev = devm_kzalloc(&client->dev, sizeof(*wdev), GFP_KERNEL); + if (wdev) { + dev_err(&pdev->dev, "Only one instance supported\n"); + return -EALREADY; + } + + wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); if (!wdev) return -ENOMEM; + wdev->mcu = mcu; arm_pm_restart = do_ts_reboot; pm_power_off = do_ts_halt; - dev_dbg(&client->dev, "%s\n", __func__); + dev_dbg(&pdev->dev, "%s\n", __func__); watchdog_set_drvdata(&ts_wdt_wdd, wdev); watchdog_set_nowayout(&ts_wdt_wdd, nowayout); @@ -190,40 +191,32 @@ static int tsreboot_probe(struct i2c_client *c, if (err) return err; - ts_wdt_ping_enable(wdev); + ts_wdt_ping_enable(); return 0; } -static const struct i2c_device_id tsreboot_id[] = { - { "ts-wdt", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tsreboot_id); - -MODULE_ALIAS("platform:ts-wdt"); - -static struct i2c_driver ts_reboot_driver = { +static struct platform_driver ts_wdt_driver = { .driver = { .name = "ts-wdt", .owner = THIS_MODULE, }, - .probe = tsreboot_probe, - .id_table = tsreboot_id, + .probe = ts_wdt_probe, }; -static int __init ts_reboot_init(void) +static int __init ts_wdt_init(void) { - return i2c_add_driver(&ts_reboot_driver); + return platform_driver_register(&ts_wdt_driver); } -subsys_initcall(ts_reboot_init); +subsys_initcall(ts_wdt_init); -static void __exit ts_reboot_exit(void) +static void __exit ts_wdt_exit(void) { - i2c_del_driver(&ts_reboot_driver); + platform_driver_unregister(&ts_wdt_driver); } -module_exit(ts_reboot_exit); +module_exit(ts_wdt_exit); MODULE_AUTHOR("Mark Featherston "); MODULE_DESCRIPTION("Technologic Systems watchdog driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ts-wdt");