[WATCHDOG] Re-factor ts_wdt to use ts-mcu-core
This commit is contained in:
parent
9f8f8c0d88
commit
7ee9473d89
@ -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
|
||||
|
@ -21,16 +21,18 @@
|
||||
#include <linux/delay.h>
|
||||
#include <asm/system_misc.h>
|
||||
|
||||
#include <linux/mfd/ts-mcu.h>
|
||||
|
||||
#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 <mark@embeddedarm.com>");
|
||||
MODULE_DESCRIPTION("Technologic Systems watchdog driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:ts-wdt");
|
||||
|
Loading…
Reference in New Issue
Block a user