1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Kontron PLD watchdog driver 4 * 5 * Copyright (c) 2010-2013 Kontron Europe GmbH 6 * Author: Michael Brunner <michael.brunner@kontron.com> 7 * 8 * Note: From the PLD watchdog point of view timeout and pretimeout are 9 * defined differently than in the kernel. 10 * First the pretimeout stage runs out before the timeout stage gets 11 * active. 12 * 13 * Kernel/API: P-----| pretimeout 14 * |-----------------------T timeout 15 * Watchdog: |-----------------P pretimeout_stage 16 * |-----T timeout_stage 17 */ 18 19 #include <linux/module.h> 20 #include <linux/moduleparam.h> 21 #include <linux/uaccess.h> 22 #include <linux/watchdog.h> 23 #include <linux/platform_device.h> 24 #include <linux/mfd/kempld.h> 25 26 #define KEMPLD_WDT_STAGE_TIMEOUT(x) (0x1b + (x) * 4) 27 #define KEMPLD_WDT_STAGE_CFG(x) (0x18 + (x)) 28 #define STAGE_CFG_GET_PRESCALER(x) (((x) & 0x30) >> 4) 29 #define STAGE_CFG_SET_PRESCALER(x) (((x) & 0x3) << 4) 30 #define STAGE_CFG_PRESCALER_MASK 0x30 31 #define STAGE_CFG_ACTION_MASK 0x7 32 #define STAGE_CFG_ASSERT (1 << 3) 33 34 #define KEMPLD_WDT_MAX_STAGES 2 35 #define KEMPLD_WDT_KICK 0x16 36 #define KEMPLD_WDT_CFG 0x17 37 #define KEMPLD_WDT_CFG_ENABLE 0x10 38 #define KEMPLD_WDT_CFG_ENABLE_LOCK 0x8 39 #define KEMPLD_WDT_CFG_GLOBAL_LOCK 0x80 40 41 enum { 42 ACTION_NONE = 0, 43 ACTION_RESET, 44 ACTION_NMI, 45 ACTION_SMI, 46 ACTION_SCI, 47 ACTION_DELAY, 48 }; 49 50 enum { 51 STAGE_TIMEOUT = 0, 52 STAGE_PRETIMEOUT, 53 }; 54 55 enum { 56 PRESCALER_21 = 0, 57 PRESCALER_17, 58 PRESCALER_12, 59 }; 60 61 static const u32 kempld_prescaler[] = { 62 [PRESCALER_21] = (1 << 21) - 1, 63 [PRESCALER_17] = (1 << 17) - 1, 64 [PRESCALER_12] = (1 << 12) - 1, 65 0, 66 }; 67 68 struct kempld_wdt_stage { 69 unsigned int id; 70 u32 mask; 71 }; 72 73 struct kempld_wdt_data { 74 struct kempld_device_data *pld; 75 struct watchdog_device wdd; 76 unsigned int pretimeout; 77 struct kempld_wdt_stage stage[KEMPLD_WDT_MAX_STAGES]; 78 u8 pm_status_store; 79 }; 80 81 #define DEFAULT_TIMEOUT 30 /* seconds */ 82 #define DEFAULT_PRETIMEOUT 0 83 84 static unsigned int timeout = DEFAULT_TIMEOUT; 85 module_param(timeout, uint, 0); 86 MODULE_PARM_DESC(timeout, 87 "Watchdog timeout in seconds. (>=0, default=" 88 __MODULE_STRING(DEFAULT_TIMEOUT) ")"); 89 90 static unsigned int pretimeout = DEFAULT_PRETIMEOUT; 91 module_param(pretimeout, uint, 0); 92 MODULE_PARM_DESC(pretimeout, 93 "Watchdog pretimeout in seconds. (>=0, default=" 94 __MODULE_STRING(DEFAULT_PRETIMEOUT) ")"); 95 96 static bool nowayout = WATCHDOG_NOWAYOUT; 97 module_param(nowayout, bool, 0); 98 MODULE_PARM_DESC(nowayout, 99 "Watchdog cannot be stopped once started (default=" 100 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 101 102 static int kempld_wdt_set_stage_action(struct kempld_wdt_data *wdt_data, 103 struct kempld_wdt_stage *stage, 104 u8 action) 105 { 106 struct kempld_device_data *pld = wdt_data->pld; 107 u8 stage_cfg; 108 109 if (!stage || !stage->mask) 110 return -EINVAL; 111 112 kempld_get_mutex(pld); 113 stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->id)); 114 stage_cfg &= ~STAGE_CFG_ACTION_MASK; 115 stage_cfg |= (action & STAGE_CFG_ACTION_MASK); 116 117 if (action == ACTION_RESET) 118 stage_cfg |= STAGE_CFG_ASSERT; 119 else 120 stage_cfg &= ~STAGE_CFG_ASSERT; 121 122 kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->id), stage_cfg); 123 kempld_release_mutex(pld); 124 125 return 0; 126 } 127 128 static int kempld_wdt_set_stage_timeout(struct kempld_wdt_data *wdt_data, 129 struct kempld_wdt_stage *stage, 130 unsigned int timeout) 131 { 132 struct kempld_device_data *pld = wdt_data->pld; 133 u32 prescaler; 134 u64 stage_timeout64; 135 u32 stage_timeout; 136 u32 remainder; 137 u8 stage_cfg; 138 139 prescaler = kempld_prescaler[PRESCALER_21]; 140 141 if (!stage) 142 return -EINVAL; 143 144 stage_timeout64 = (u64)timeout * pld->pld_clock; 145 remainder = do_div(stage_timeout64, prescaler); 146 if (remainder) 147 stage_timeout64++; 148 149 if (stage_timeout64 > stage->mask) 150 return -EINVAL; 151 152 stage_timeout = stage_timeout64 & stage->mask; 153 154 kempld_get_mutex(pld); 155 stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->id)); 156 stage_cfg &= ~STAGE_CFG_PRESCALER_MASK; 157 stage_cfg |= STAGE_CFG_SET_PRESCALER(PRESCALER_21); 158 kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->id), stage_cfg); 159 kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(stage->id), 160 stage_timeout); 161 kempld_release_mutex(pld); 162 163 return 0; 164 } 165 166 /* 167 * kempld_get_mutex must be called prior to calling this function. 168 */ 169 static unsigned int kempld_wdt_get_timeout(struct kempld_wdt_data *wdt_data, 170 struct kempld_wdt_stage *stage) 171 { 172 struct kempld_device_data *pld = wdt_data->pld; 173 unsigned int timeout; 174 u64 stage_timeout; 175 u32 prescaler; 176 u32 remainder; 177 u8 stage_cfg; 178 179 if (!stage->mask) 180 return 0; 181 182 stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->id)); 183 stage_timeout = kempld_read32(pld, KEMPLD_WDT_STAGE_TIMEOUT(stage->id)); 184 prescaler = kempld_prescaler[STAGE_CFG_GET_PRESCALER(stage_cfg)]; 185 186 stage_timeout = (stage_timeout & stage->mask) * prescaler; 187 remainder = do_div(stage_timeout, pld->pld_clock); 188 if (remainder) 189 stage_timeout++; 190 191 timeout = stage_timeout; 192 WARN_ON_ONCE(timeout != stage_timeout); 193 194 return timeout; 195 } 196 197 static int kempld_wdt_set_timeout(struct watchdog_device *wdd, 198 unsigned int timeout) 199 { 200 struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); 201 struct kempld_wdt_stage *pretimeout_stage; 202 struct kempld_wdt_stage *timeout_stage; 203 int ret; 204 205 timeout_stage = &wdt_data->stage[STAGE_TIMEOUT]; 206 pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT]; 207 208 if (pretimeout_stage->mask && wdt_data->pretimeout > 0) 209 timeout = wdt_data->pretimeout; 210 211 ret = kempld_wdt_set_stage_action(wdt_data, timeout_stage, 212 ACTION_RESET); 213 if (ret) 214 return ret; 215 ret = kempld_wdt_set_stage_timeout(wdt_data, timeout_stage, 216 timeout); 217 if (ret) 218 return ret; 219 220 wdd->timeout = timeout; 221 return 0; 222 } 223 224 static int kempld_wdt_set_pretimeout(struct watchdog_device *wdd, 225 unsigned int pretimeout) 226 { 227 struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); 228 struct kempld_wdt_stage *pretimeout_stage; 229 u8 action = ACTION_NONE; 230 int ret; 231 232 pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT]; 233 234 if (!pretimeout_stage->mask) 235 return -ENXIO; 236 237 if (pretimeout > wdd->timeout) 238 return -EINVAL; 239 240 if (pretimeout > 0) 241 action = ACTION_NMI; 242 243 ret = kempld_wdt_set_stage_action(wdt_data, pretimeout_stage, 244 action); 245 if (ret) 246 return ret; 247 ret = kempld_wdt_set_stage_timeout(wdt_data, pretimeout_stage, 248 wdd->timeout - pretimeout); 249 if (ret) 250 return ret; 251 252 wdt_data->pretimeout = pretimeout; 253 return 0; 254 } 255 256 static void kempld_wdt_update_timeouts(struct kempld_wdt_data *wdt_data) 257 { 258 struct kempld_device_data *pld = wdt_data->pld; 259 struct kempld_wdt_stage *pretimeout_stage; 260 struct kempld_wdt_stage *timeout_stage; 261 unsigned int pretimeout, timeout; 262 263 pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT]; 264 timeout_stage = &wdt_data->stage[STAGE_TIMEOUT]; 265 266 kempld_get_mutex(pld); 267 pretimeout = kempld_wdt_get_timeout(wdt_data, pretimeout_stage); 268 timeout = kempld_wdt_get_timeout(wdt_data, timeout_stage); 269 kempld_release_mutex(pld); 270 271 if (pretimeout) 272 wdt_data->pretimeout = timeout; 273 else 274 wdt_data->pretimeout = 0; 275 276 wdt_data->wdd.timeout = pretimeout + timeout; 277 } 278 279 static int kempld_wdt_start(struct watchdog_device *wdd) 280 { 281 struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); 282 struct kempld_device_data *pld = wdt_data->pld; 283 u8 status; 284 int ret; 285 286 ret = kempld_wdt_set_timeout(wdd, wdd->timeout); 287 if (ret) 288 return ret; 289 290 kempld_get_mutex(pld); 291 status = kempld_read8(pld, KEMPLD_WDT_CFG); 292 status |= KEMPLD_WDT_CFG_ENABLE; 293 kempld_write8(pld, KEMPLD_WDT_CFG, status); 294 status = kempld_read8(pld, KEMPLD_WDT_CFG); 295 kempld_release_mutex(pld); 296 297 /* Check if the watchdog was enabled */ 298 if (!(status & KEMPLD_WDT_CFG_ENABLE)) 299 return -EACCES; 300 301 return 0; 302 } 303 304 static int kempld_wdt_stop(struct watchdog_device *wdd) 305 { 306 struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); 307 struct kempld_device_data *pld = wdt_data->pld; 308 u8 status; 309 310 kempld_get_mutex(pld); 311 status = kempld_read8(pld, KEMPLD_WDT_CFG); 312 status &= ~KEMPLD_WDT_CFG_ENABLE; 313 kempld_write8(pld, KEMPLD_WDT_CFG, status); 314 status = kempld_read8(pld, KEMPLD_WDT_CFG); 315 kempld_release_mutex(pld); 316 317 /* Check if the watchdog was disabled */ 318 if (status & KEMPLD_WDT_CFG_ENABLE) 319 return -EACCES; 320 321 return 0; 322 } 323 324 static int kempld_wdt_keepalive(struct watchdog_device *wdd) 325 { 326 struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); 327 struct kempld_device_data *pld = wdt_data->pld; 328 329 kempld_get_mutex(pld); 330 kempld_write8(pld, KEMPLD_WDT_KICK, 'K'); 331 kempld_release_mutex(pld); 332 333 return 0; 334 } 335 336 static long kempld_wdt_ioctl(struct watchdog_device *wdd, unsigned int cmd, 337 unsigned long arg) 338 { 339 struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); 340 void __user *argp = (void __user *)arg; 341 int ret = -ENOIOCTLCMD; 342 int __user *p = argp; 343 int new_value; 344 345 switch (cmd) { 346 case WDIOC_SETPRETIMEOUT: 347 if (get_user(new_value, p)) 348 return -EFAULT; 349 ret = kempld_wdt_set_pretimeout(wdd, new_value); 350 if (ret) 351 return ret; 352 ret = kempld_wdt_keepalive(wdd); 353 break; 354 case WDIOC_GETPRETIMEOUT: 355 ret = put_user(wdt_data->pretimeout, (int __user *)arg); 356 break; 357 } 358 359 return ret; 360 } 361 362 static int kempld_wdt_probe_stages(struct watchdog_device *wdd) 363 { 364 struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); 365 struct kempld_device_data *pld = wdt_data->pld; 366 struct kempld_wdt_stage *pretimeout_stage; 367 struct kempld_wdt_stage *timeout_stage; 368 u8 index, data, data_orig; 369 u32 mask; 370 int i, j; 371 372 pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT]; 373 timeout_stage = &wdt_data->stage[STAGE_TIMEOUT]; 374 375 pretimeout_stage->mask = 0; 376 timeout_stage->mask = 0; 377 378 for (i = 0; i < 3; i++) { 379 index = KEMPLD_WDT_STAGE_TIMEOUT(i); 380 mask = 0; 381 382 kempld_get_mutex(pld); 383 /* Probe each byte individually. */ 384 for (j = 0; j < 4; j++) { 385 data_orig = kempld_read8(pld, index + j); 386 kempld_write8(pld, index + j, 0x00); 387 data = kempld_read8(pld, index + j); 388 /* A failed write means this byte is reserved */ 389 if (data != 0x00) 390 break; 391 kempld_write8(pld, index + j, data_orig); 392 mask |= 0xff << (j * 8); 393 } 394 kempld_release_mutex(pld); 395 396 /* Assign available stages to timeout and pretimeout */ 397 if (!timeout_stage->mask) { 398 timeout_stage->mask = mask; 399 timeout_stage->id = i; 400 } else { 401 if (pld->feature_mask & KEMPLD_FEATURE_BIT_NMI) { 402 pretimeout_stage->mask = timeout_stage->mask; 403 timeout_stage->mask = mask; 404 pretimeout_stage->id = timeout_stage->id; 405 timeout_stage->id = i; 406 } 407 break; 408 } 409 } 410 411 if (!timeout_stage->mask) 412 return -ENODEV; 413 414 return 0; 415 } 416 417 static const struct watchdog_info kempld_wdt_info = { 418 .identity = "KEMPLD Watchdog", 419 .options = WDIOF_SETTIMEOUT | 420 WDIOF_KEEPALIVEPING | 421 WDIOF_MAGICCLOSE | 422 WDIOF_PRETIMEOUT 423 }; 424 425 static const struct watchdog_ops kempld_wdt_ops = { 426 .owner = THIS_MODULE, 427 .start = kempld_wdt_start, 428 .stop = kempld_wdt_stop, 429 .ping = kempld_wdt_keepalive, 430 .set_timeout = kempld_wdt_set_timeout, 431 .ioctl = kempld_wdt_ioctl, 432 }; 433 434 static int kempld_wdt_probe(struct platform_device *pdev) 435 { 436 struct kempld_device_data *pld = dev_get_drvdata(pdev->dev.parent); 437 struct kempld_wdt_data *wdt_data; 438 struct device *dev = &pdev->dev; 439 struct watchdog_device *wdd; 440 u8 status; 441 int ret = 0; 442 443 wdt_data = devm_kzalloc(dev, sizeof(*wdt_data), GFP_KERNEL); 444 if (!wdt_data) 445 return -ENOMEM; 446 447 wdt_data->pld = pld; 448 wdd = &wdt_data->wdd; 449 wdd->parent = dev; 450 451 kempld_get_mutex(pld); 452 status = kempld_read8(pld, KEMPLD_WDT_CFG); 453 kempld_release_mutex(pld); 454 455 /* Enable nowayout if watchdog is already locked */ 456 if (status & (KEMPLD_WDT_CFG_ENABLE_LOCK | 457 KEMPLD_WDT_CFG_GLOBAL_LOCK)) { 458 if (!nowayout) 459 dev_warn(dev, 460 "Forcing nowayout - watchdog lock enabled!\n"); 461 nowayout = true; 462 } 463 464 wdd->info = &kempld_wdt_info; 465 wdd->ops = &kempld_wdt_ops; 466 467 watchdog_set_drvdata(wdd, wdt_data); 468 watchdog_set_nowayout(wdd, nowayout); 469 470 ret = kempld_wdt_probe_stages(wdd); 471 if (ret) 472 return ret; 473 474 kempld_wdt_set_timeout(wdd, timeout); 475 kempld_wdt_set_pretimeout(wdd, pretimeout); 476 477 /* Check if watchdog is already enabled */ 478 if (status & KEMPLD_WDT_CFG_ENABLE) { 479 /* Get current watchdog settings */ 480 kempld_wdt_update_timeouts(wdt_data); 481 dev_info(dev, "Watchdog was already enabled\n"); 482 } 483 484 platform_set_drvdata(pdev, wdt_data); 485 watchdog_stop_on_reboot(wdd); 486 watchdog_stop_on_unregister(wdd); 487 ret = devm_watchdog_register_device(dev, wdd); 488 if (ret) 489 return ret; 490 491 dev_info(dev, "Watchdog registered with %ds timeout\n", wdd->timeout); 492 493 return 0; 494 } 495 496 /* Disable watchdog if it is active during suspend */ 497 static int kempld_wdt_suspend(struct platform_device *pdev, 498 pm_message_t message) 499 { 500 struct kempld_wdt_data *wdt_data = platform_get_drvdata(pdev); 501 struct kempld_device_data *pld = wdt_data->pld; 502 struct watchdog_device *wdd = &wdt_data->wdd; 503 504 kempld_get_mutex(pld); 505 wdt_data->pm_status_store = kempld_read8(pld, KEMPLD_WDT_CFG); 506 kempld_release_mutex(pld); 507 508 kempld_wdt_update_timeouts(wdt_data); 509 510 if (wdt_data->pm_status_store & KEMPLD_WDT_CFG_ENABLE) 511 return kempld_wdt_stop(wdd); 512 513 return 0; 514 } 515 516 /* Enable watchdog and configure it if necessary */ 517 static int kempld_wdt_resume(struct platform_device *pdev) 518 { 519 struct kempld_wdt_data *wdt_data = platform_get_drvdata(pdev); 520 struct watchdog_device *wdd = &wdt_data->wdd; 521 522 /* 523 * If watchdog was stopped before suspend be sure it gets disabled 524 * again, for the case BIOS has enabled it during resume 525 */ 526 if (wdt_data->pm_status_store & KEMPLD_WDT_CFG_ENABLE) 527 return kempld_wdt_start(wdd); 528 else 529 return kempld_wdt_stop(wdd); 530 } 531 532 static struct platform_driver kempld_wdt_driver = { 533 .driver = { 534 .name = "kempld-wdt", 535 }, 536 .probe = kempld_wdt_probe, 537 .suspend = pm_ptr(kempld_wdt_suspend), 538 .resume = pm_ptr(kempld_wdt_resume), 539 }; 540 541 module_platform_driver(kempld_wdt_driver); 542 543 MODULE_DESCRIPTION("KEM PLD Watchdog Driver"); 544 MODULE_AUTHOR("Michael Brunner <michael.brunner@kontron.com>"); 545 MODULE_LICENSE("GPL"); 546