1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Watchdog driver for the wm831x PMICs 4 * 5 * Copyright (C) 2009 Wolfson Microelectronics 6 */ 7 8 #include <linux/module.h> 9 #include <linux/moduleparam.h> 10 #include <linux/types.h> 11 #include <linux/kernel.h> 12 #include <linux/slab.h> 13 #include <linux/platform_device.h> 14 #include <linux/watchdog.h> 15 #include <linux/uaccess.h> 16 17 #include <linux/mfd/wm831x/core.h> 18 #include <linux/mfd/wm831x/pdata.h> 19 #include <linux/mfd/wm831x/watchdog.h> 20 21 static bool nowayout = WATCHDOG_NOWAYOUT; 22 module_param(nowayout, bool, 0); 23 MODULE_PARM_DESC(nowayout, 24 "Watchdog cannot be stopped once started (default=" 25 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 26 27 struct wm831x_wdt_drvdata { 28 struct watchdog_device wdt; 29 struct wm831x *wm831x; 30 struct mutex lock; 31 int update_state; 32 }; 33 34 /* We can't use the sub-second values here but they're included 35 * for completeness. */ 36 static struct { 37 unsigned int time; /* Seconds */ 38 u16 val; /* WDOG_TO value */ 39 } wm831x_wdt_cfgs[] = { 40 { 1, 2 }, 41 { 2, 3 }, 42 { 4, 4 }, 43 { 8, 5 }, 44 { 16, 6 }, 45 { 32, 7 }, 46 { 33, 7 }, /* Actually 32.768s so include both, others round down */ 47 }; 48 49 static int wm831x_wdt_start(struct watchdog_device *wdt_dev) 50 { 51 struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev); 52 struct wm831x *wm831x = driver_data->wm831x; 53 int ret; 54 55 mutex_lock(&driver_data->lock); 56 57 ret = wm831x_reg_unlock(wm831x); 58 if (ret == 0) { 59 ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG, 60 WM831X_WDOG_ENA, WM831X_WDOG_ENA); 61 wm831x_reg_lock(wm831x); 62 } else { 63 dev_err(wm831x->dev, "Failed to unlock security key: %d\n", 64 ret); 65 } 66 67 mutex_unlock(&driver_data->lock); 68 69 return ret; 70 } 71 72 static int wm831x_wdt_stop(struct watchdog_device *wdt_dev) 73 { 74 struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev); 75 struct wm831x *wm831x = driver_data->wm831x; 76 int ret; 77 78 mutex_lock(&driver_data->lock); 79 80 ret = wm831x_reg_unlock(wm831x); 81 if (ret == 0) { 82 ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG, 83 WM831X_WDOG_ENA, 0); 84 wm831x_reg_lock(wm831x); 85 } else { 86 dev_err(wm831x->dev, "Failed to unlock security key: %d\n", 87 ret); 88 } 89 90 mutex_unlock(&driver_data->lock); 91 92 return ret; 93 } 94 95 static int wm831x_wdt_ping(struct watchdog_device *wdt_dev) 96 { 97 struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev); 98 struct wm831x *wm831x = driver_data->wm831x; 99 int ret; 100 u16 reg; 101 102 mutex_lock(&driver_data->lock); 103 104 reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG); 105 106 if (!(reg & WM831X_WDOG_RST_SRC)) { 107 dev_err(wm831x->dev, "Hardware watchdog update unsupported\n"); 108 ret = -EINVAL; 109 goto out; 110 } 111 112 reg |= WM831X_WDOG_RESET; 113 114 ret = wm831x_reg_unlock(wm831x); 115 if (ret == 0) { 116 ret = wm831x_reg_write(wm831x, WM831X_WATCHDOG, reg); 117 wm831x_reg_lock(wm831x); 118 } else { 119 dev_err(wm831x->dev, "Failed to unlock security key: %d\n", 120 ret); 121 } 122 123 out: 124 mutex_unlock(&driver_data->lock); 125 126 return ret; 127 } 128 129 static int wm831x_wdt_set_timeout(struct watchdog_device *wdt_dev, 130 unsigned int timeout) 131 { 132 struct wm831x_wdt_drvdata *driver_data = watchdog_get_drvdata(wdt_dev); 133 struct wm831x *wm831x = driver_data->wm831x; 134 int ret, i; 135 136 for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++) 137 if (wm831x_wdt_cfgs[i].time == timeout) 138 break; 139 if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) 140 return -EINVAL; 141 142 ret = wm831x_reg_unlock(wm831x); 143 if (ret == 0) { 144 ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG, 145 WM831X_WDOG_TO_MASK, 146 wm831x_wdt_cfgs[i].val); 147 wm831x_reg_lock(wm831x); 148 } else { 149 dev_err(wm831x->dev, "Failed to unlock security key: %d\n", 150 ret); 151 } 152 153 wdt_dev->timeout = timeout; 154 155 return ret; 156 } 157 158 static const struct watchdog_info wm831x_wdt_info = { 159 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 160 .identity = "WM831x Watchdog", 161 }; 162 163 static const struct watchdog_ops wm831x_wdt_ops = { 164 .owner = THIS_MODULE, 165 .start = wm831x_wdt_start, 166 .stop = wm831x_wdt_stop, 167 .ping = wm831x_wdt_ping, 168 .set_timeout = wm831x_wdt_set_timeout, 169 }; 170 171 static int wm831x_wdt_probe(struct platform_device *pdev) 172 { 173 struct device *dev = &pdev->dev; 174 struct wm831x *wm831x = dev_get_drvdata(dev->parent); 175 struct wm831x_pdata *chip_pdata = dev_get_platdata(dev->parent); 176 struct wm831x_watchdog_pdata *pdata; 177 struct wm831x_wdt_drvdata *driver_data; 178 struct watchdog_device *wm831x_wdt; 179 int reg, ret, i; 180 181 ret = wm831x_reg_read(wm831x, WM831X_WATCHDOG); 182 if (ret < 0) { 183 dev_err(wm831x->dev, "Failed to read watchdog status: %d\n", 184 ret); 185 return ret; 186 } 187 reg = ret; 188 189 if (reg & WM831X_WDOG_DEBUG) 190 dev_warn(wm831x->dev, "Watchdog is paused\n"); 191 192 driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL); 193 if (!driver_data) 194 return -ENOMEM; 195 196 mutex_init(&driver_data->lock); 197 driver_data->wm831x = wm831x; 198 199 wm831x_wdt = &driver_data->wdt; 200 201 wm831x_wdt->info = &wm831x_wdt_info; 202 wm831x_wdt->ops = &wm831x_wdt_ops; 203 wm831x_wdt->parent = dev; 204 watchdog_set_nowayout(wm831x_wdt, nowayout); 205 watchdog_set_drvdata(wm831x_wdt, driver_data); 206 207 reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG); 208 reg &= WM831X_WDOG_TO_MASK; 209 for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++) 210 if (wm831x_wdt_cfgs[i].val == reg) 211 break; 212 if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) 213 dev_warn(wm831x->dev, 214 "Unknown watchdog timeout: %x\n", reg); 215 else 216 wm831x_wdt->timeout = wm831x_wdt_cfgs[i].time; 217 218 /* Apply any configuration */ 219 if (chip_pdata) 220 pdata = chip_pdata->watchdog; 221 else 222 pdata = NULL; 223 224 if (pdata) { 225 reg &= ~(WM831X_WDOG_SECACT_MASK | WM831X_WDOG_PRIMACT_MASK | 226 WM831X_WDOG_RST_SRC); 227 228 reg |= pdata->primary << WM831X_WDOG_PRIMACT_SHIFT; 229 reg |= pdata->secondary << WM831X_WDOG_SECACT_SHIFT; 230 reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT; 231 232 ret = wm831x_reg_unlock(wm831x); 233 if (ret == 0) { 234 ret = wm831x_reg_write(wm831x, WM831X_WATCHDOG, reg); 235 wm831x_reg_lock(wm831x); 236 } else { 237 dev_err(wm831x->dev, 238 "Failed to unlock security key: %d\n", ret); 239 return ret; 240 } 241 } 242 243 return devm_watchdog_register_device(dev, &driver_data->wdt); 244 } 245 246 static struct platform_driver wm831x_wdt_driver = { 247 .probe = wm831x_wdt_probe, 248 .driver = { 249 .name = "wm831x-watchdog", 250 }, 251 }; 252 253 module_platform_driver(wm831x_wdt_driver); 254 255 MODULE_AUTHOR("Mark Brown"); 256 MODULE_DESCRIPTION("WM831x Watchdog"); 257 MODULE_LICENSE("GPL"); 258 MODULE_ALIAS("platform:wm831x-watchdog"); 259