cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

twl4030_wdt.c (2983B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) Nokia Corporation
      4 *
      5 * Written by Timo Kokkonen <timo.t.kokkonen at nokia.com>
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/types.h>
     10#include <linux/slab.h>
     11#include <linux/kernel.h>
     12#include <linux/watchdog.h>
     13#include <linux/platform_device.h>
     14#include <linux/mfd/twl.h>
     15
     16#define TWL4030_WATCHDOG_CFG_REG_OFFS	0x3
     17
     18static bool nowayout = WATCHDOG_NOWAYOUT;
     19module_param(nowayout, bool, 0);
     20MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
     21	"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
     22
     23static int twl4030_wdt_write(unsigned char val)
     24{
     25	return twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, val,
     26					TWL4030_WATCHDOG_CFG_REG_OFFS);
     27}
     28
     29static int twl4030_wdt_start(struct watchdog_device *wdt)
     30{
     31	return twl4030_wdt_write(wdt->timeout + 1);
     32}
     33
     34static int twl4030_wdt_stop(struct watchdog_device *wdt)
     35{
     36	return twl4030_wdt_write(0);
     37}
     38
     39static int twl4030_wdt_set_timeout(struct watchdog_device *wdt,
     40				   unsigned int timeout)
     41{
     42	wdt->timeout = timeout;
     43	return 0;
     44}
     45
     46static const struct watchdog_info twl4030_wdt_info = {
     47	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
     48	.identity = "TWL4030 Watchdog",
     49};
     50
     51static const struct watchdog_ops twl4030_wdt_ops = {
     52	.owner		= THIS_MODULE,
     53	.start		= twl4030_wdt_start,
     54	.stop		= twl4030_wdt_stop,
     55	.set_timeout	= twl4030_wdt_set_timeout,
     56};
     57
     58static int twl4030_wdt_probe(struct platform_device *pdev)
     59{
     60	struct device *dev = &pdev->dev;
     61	struct watchdog_device *wdt;
     62
     63	wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
     64	if (!wdt)
     65		return -ENOMEM;
     66
     67	wdt->info		= &twl4030_wdt_info;
     68	wdt->ops		= &twl4030_wdt_ops;
     69	wdt->status		= 0;
     70	wdt->timeout		= 30;
     71	wdt->min_timeout	= 1;
     72	wdt->max_timeout	= 30;
     73	wdt->parent = dev;
     74
     75	watchdog_set_nowayout(wdt, nowayout);
     76	platform_set_drvdata(pdev, wdt);
     77
     78	twl4030_wdt_stop(wdt);
     79
     80	return devm_watchdog_register_device(dev, wdt);
     81}
     82
     83#ifdef CONFIG_PM
     84static int twl4030_wdt_suspend(struct platform_device *pdev, pm_message_t state)
     85{
     86	struct watchdog_device *wdt = platform_get_drvdata(pdev);
     87	if (watchdog_active(wdt))
     88		return twl4030_wdt_stop(wdt);
     89
     90	return 0;
     91}
     92
     93static int twl4030_wdt_resume(struct platform_device *pdev)
     94{
     95	struct watchdog_device *wdt = platform_get_drvdata(pdev);
     96	if (watchdog_active(wdt))
     97		return twl4030_wdt_start(wdt);
     98
     99	return 0;
    100}
    101#else
    102#define twl4030_wdt_suspend        NULL
    103#define twl4030_wdt_resume         NULL
    104#endif
    105
    106static const struct of_device_id twl_wdt_of_match[] = {
    107	{ .compatible = "ti,twl4030-wdt", },
    108	{ },
    109};
    110MODULE_DEVICE_TABLE(of, twl_wdt_of_match);
    111
    112static struct platform_driver twl4030_wdt_driver = {
    113	.probe		= twl4030_wdt_probe,
    114	.suspend	= twl4030_wdt_suspend,
    115	.resume		= twl4030_wdt_resume,
    116	.driver		= {
    117		.name		= "twl4030_wdt",
    118		.of_match_table	= twl_wdt_of_match,
    119	},
    120};
    121
    122module_platform_driver(twl4030_wdt_driver);
    123
    124MODULE_AUTHOR("Nokia Corporation");
    125MODULE_LICENSE("GPL");
    126MODULE_ALIAS("platform:twl4030_wdt");
    127