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