0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #include <linux/module.h>
0011 #include <linux/moduleparam.h>
0012 #include <linux/types.h>
0013 #include <linux/kernel.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/watchdog.h>
0016 #include <linux/uaccess.h>
0017 #include <linux/mfd/wm8350/core.h>
0018
0019 static bool nowayout = WATCHDOG_NOWAYOUT;
0020 module_param(nowayout, bool, 0);
0021 MODULE_PARM_DESC(nowayout,
0022 "Watchdog cannot be stopped once started (default="
0023 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0024
0025 static DEFINE_MUTEX(wdt_mutex);
0026
0027 static struct {
0028 unsigned int time;
0029 u16 val;
0030 } wm8350_wdt_cfgs[] = {
0031 { 1, 0x02 },
0032 { 2, 0x04 },
0033 { 4, 0x05 },
0034 };
0035
0036 static int wm8350_wdt_set_timeout(struct watchdog_device *wdt_dev,
0037 unsigned int timeout)
0038 {
0039 struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
0040 int ret, i;
0041 u16 reg;
0042
0043 for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++)
0044 if (wm8350_wdt_cfgs[i].time == timeout)
0045 break;
0046 if (i == ARRAY_SIZE(wm8350_wdt_cfgs))
0047 return -EINVAL;
0048
0049 mutex_lock(&wdt_mutex);
0050 wm8350_reg_unlock(wm8350);
0051
0052 reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
0053 reg &= ~WM8350_WDOG_TO_MASK;
0054 reg |= wm8350_wdt_cfgs[i].val;
0055 ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
0056
0057 wm8350_reg_lock(wm8350);
0058 mutex_unlock(&wdt_mutex);
0059
0060 wdt_dev->timeout = timeout;
0061 return ret;
0062 }
0063
0064 static int wm8350_wdt_start(struct watchdog_device *wdt_dev)
0065 {
0066 struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
0067 int ret;
0068 u16 reg;
0069
0070 mutex_lock(&wdt_mutex);
0071 wm8350_reg_unlock(wm8350);
0072
0073 reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
0074 reg &= ~WM8350_WDOG_MODE_MASK;
0075 reg |= 0x20;
0076 ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
0077
0078 wm8350_reg_lock(wm8350);
0079 mutex_unlock(&wdt_mutex);
0080
0081 return ret;
0082 }
0083
0084 static int wm8350_wdt_stop(struct watchdog_device *wdt_dev)
0085 {
0086 struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
0087 int ret;
0088 u16 reg;
0089
0090 mutex_lock(&wdt_mutex);
0091 wm8350_reg_unlock(wm8350);
0092
0093 reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
0094 reg &= ~WM8350_WDOG_MODE_MASK;
0095 ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
0096
0097 wm8350_reg_lock(wm8350);
0098 mutex_unlock(&wdt_mutex);
0099
0100 return ret;
0101 }
0102
0103 static int wm8350_wdt_ping(struct watchdog_device *wdt_dev)
0104 {
0105 struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
0106 int ret;
0107 u16 reg;
0108
0109 mutex_lock(&wdt_mutex);
0110
0111 reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
0112 ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
0113
0114 mutex_unlock(&wdt_mutex);
0115
0116 return ret;
0117 }
0118
0119 static const struct watchdog_info wm8350_wdt_info = {
0120 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
0121 .identity = "WM8350 Watchdog",
0122 };
0123
0124 static const struct watchdog_ops wm8350_wdt_ops = {
0125 .owner = THIS_MODULE,
0126 .start = wm8350_wdt_start,
0127 .stop = wm8350_wdt_stop,
0128 .ping = wm8350_wdt_ping,
0129 .set_timeout = wm8350_wdt_set_timeout,
0130 };
0131
0132 static struct watchdog_device wm8350_wdt = {
0133 .info = &wm8350_wdt_info,
0134 .ops = &wm8350_wdt_ops,
0135 .timeout = 4,
0136 .min_timeout = 1,
0137 .max_timeout = 4,
0138 };
0139
0140 static int wm8350_wdt_probe(struct platform_device *pdev)
0141 {
0142 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
0143
0144 if (!wm8350) {
0145 pr_err("No driver data supplied\n");
0146 return -ENODEV;
0147 }
0148
0149 watchdog_set_nowayout(&wm8350_wdt, nowayout);
0150 watchdog_set_drvdata(&wm8350_wdt, wm8350);
0151 wm8350_wdt.parent = &pdev->dev;
0152
0153
0154 wm8350_wdt_set_timeout(&wm8350_wdt, 4);
0155
0156 return watchdog_register_device(&wm8350_wdt);
0157 }
0158
0159 static int wm8350_wdt_remove(struct platform_device *pdev)
0160 {
0161 watchdog_unregister_device(&wm8350_wdt);
0162 return 0;
0163 }
0164
0165 static struct platform_driver wm8350_wdt_driver = {
0166 .probe = wm8350_wdt_probe,
0167 .remove = wm8350_wdt_remove,
0168 .driver = {
0169 .name = "wm8350-wdt",
0170 },
0171 };
0172
0173 module_platform_driver(wm8350_wdt_driver);
0174
0175 MODULE_AUTHOR("Mark Brown");
0176 MODULE_DESCRIPTION("WM8350 Watchdog");
0177 MODULE_LICENSE("GPL");
0178 MODULE_ALIAS("platform:wm8350-wdt");