1 /* 2 * Cadence WDT driver - Used by Xilinx Zynq 3 * 4 * Copyright (C) 2010 - 2014 Xilinx, Inc. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <linux/clk.h> 13 #include <linux/init.h> 14 #include <linux/interrupt.h> 15 #include <linux/io.h> 16 #include <linux/irq.h> 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/of.h> 20 #include <linux/platform_device.h> 21 #include <linux/reboot.h> 22 #include <linux/watchdog.h> 23 24 #define CDNS_WDT_DEFAULT_TIMEOUT 10 25 /* Supports 1 - 516 sec */ 26 #define CDNS_WDT_MIN_TIMEOUT 1 27 #define CDNS_WDT_MAX_TIMEOUT 516 28 29 /* Restart key */ 30 #define CDNS_WDT_RESTART_KEY 0x00001999 31 32 /* Counter register access key */ 33 #define CDNS_WDT_REGISTER_ACCESS_KEY 0x00920000 34 35 /* Counter value divisor */ 36 #define CDNS_WDT_COUNTER_VALUE_DIVISOR 0x1000 37 38 /* Clock prescaler value and selection */ 39 #define CDNS_WDT_PRESCALE_64 64 40 #define CDNS_WDT_PRESCALE_512 512 41 #define CDNS_WDT_PRESCALE_4096 4096 42 #define CDNS_WDT_PRESCALE_SELECT_64 1 43 #define CDNS_WDT_PRESCALE_SELECT_512 2 44 #define CDNS_WDT_PRESCALE_SELECT_4096 3 45 46 /* Input clock frequency */ 47 #define CDNS_WDT_CLK_10MHZ 10000000 48 #define CDNS_WDT_CLK_75MHZ 75000000 49 50 /* Counter maximum value */ 51 #define CDNS_WDT_COUNTER_MAX 0xFFF 52 53 static int wdt_timeout = CDNS_WDT_DEFAULT_TIMEOUT; 54 static int nowayout = WATCHDOG_NOWAYOUT; 55 56 module_param(wdt_timeout, int, 0); 57 MODULE_PARM_DESC(wdt_timeout, 58 "Watchdog time in seconds. (default=" 59 __MODULE_STRING(CDNS_WDT_DEFAULT_TIMEOUT) ")"); 60 61 module_param(nowayout, int, 0); 62 MODULE_PARM_DESC(nowayout, 63 "Watchdog cannot be stopped once started (default=" 64 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 65 66 /** 67 * struct cdns_wdt - Watchdog device structure 68 * @regs: baseaddress of device 69 * @rst: reset flag 70 * @clk: struct clk * of a clock source 71 * @prescaler: for saving prescaler value 72 * @ctrl_clksel: counter clock prescaler selection 73 * @io_lock: spinlock for IO register access 74 * @cdns_wdt_device: watchdog device structure 75 * @cdns_wdt_notifier: notifier structure 76 * 77 * Structure containing parameters specific to cadence watchdog. 78 */ 79 struct cdns_wdt { 80 void __iomem *regs; 81 bool rst; 82 struct clk *clk; 83 u32 prescaler; 84 u32 ctrl_clksel; 85 spinlock_t io_lock; 86 struct watchdog_device cdns_wdt_device; 87 struct notifier_block cdns_wdt_notifier; 88 }; 89 90 /* Write access to Registers */ 91 static inline void cdns_wdt_writereg(struct cdns_wdt *wdt, u32 offset, u32 val) 92 { 93 writel_relaxed(val, wdt->regs + offset); 94 } 95 96 /*************************Register Map**************************************/ 97 98 /* Register Offsets for the WDT */ 99 #define CDNS_WDT_ZMR_OFFSET 0x0 /* Zero Mode Register */ 100 #define CDNS_WDT_CCR_OFFSET 0x4 /* Counter Control Register */ 101 #define CDNS_WDT_RESTART_OFFSET 0x8 /* Restart Register */ 102 #define CDNS_WDT_SR_OFFSET 0xC /* Status Register */ 103 104 /* 105 * Zero Mode Register - This register controls how the time out is indicated 106 * and also contains the access code to allow writes to the register (0xABC). 107 */ 108 #define CDNS_WDT_ZMR_WDEN_MASK 0x00000001 /* Enable the WDT */ 109 #define CDNS_WDT_ZMR_RSTEN_MASK 0x00000002 /* Enable the reset output */ 110 #define CDNS_WDT_ZMR_IRQEN_MASK 0x00000004 /* Enable IRQ output */ 111 #define CDNS_WDT_ZMR_RSTLEN_16 0x00000030 /* Reset pulse of 16 pclk cycles */ 112 #define CDNS_WDT_ZMR_ZKEY_VAL 0x00ABC000 /* Access key, 0xABC << 12 */ 113 /* 114 * Counter Control register - This register controls how fast the timer runs 115 * and the reset value and also contains the access code to allow writes to 116 * the register. 117 */ 118 #define CDNS_WDT_CCR_CRV_MASK 0x00003FFC /* Counter reset value */ 119 120 /** 121 * cdns_wdt_stop - Stop the watchdog. 122 * 123 * @wdd: watchdog device 124 * 125 * Read the contents of the ZMR register, clear the WDEN bit 126 * in the register and set the access key for successful write. 127 * 128 * Return: always 0 129 */ 130 static int cdns_wdt_stop(struct watchdog_device *wdd) 131 { 132 struct cdns_wdt *wdt = watchdog_get_drvdata(wdd); 133 134 spin_lock(&wdt->io_lock); 135 cdns_wdt_writereg(wdt, CDNS_WDT_ZMR_OFFSET, 136 CDNS_WDT_ZMR_ZKEY_VAL & (~CDNS_WDT_ZMR_WDEN_MASK)); 137 spin_unlock(&wdt->io_lock); 138 139 return 0; 140 } 141 142 /** 143 * cdns_wdt_reload - Reload the watchdog timer (i.e. pat the watchdog). 144 * 145 * @wdd: watchdog device 146 * 147 * Write the restart key value (0x00001999) to the restart register. 148 * 149 * Return: always 0 150 */ 151 static int cdns_wdt_reload(struct watchdog_device *wdd) 152 { 153 struct cdns_wdt *wdt = watchdog_get_drvdata(wdd); 154 155 spin_lock(&wdt->io_lock); 156 cdns_wdt_writereg(wdt, CDNS_WDT_RESTART_OFFSET, 157 CDNS_WDT_RESTART_KEY); 158 spin_unlock(&wdt->io_lock); 159 160 return 0; 161 } 162 163 /** 164 * cdns_wdt_start - Enable and start the watchdog. 165 * 166 * @wdd: watchdog device 167 * 168 * The counter value is calculated according to the formula: 169 * calculated count = (timeout * clock) / prescaler + 1. 170 * The calculated count is divided by 0x1000 to obtain the field value 171 * to write to counter control register. 172 * Clears the contents of prescaler and counter reset value. Sets the 173 * prescaler to 4096 and the calculated count and access key 174 * to write to CCR Register. 175 * Sets the WDT (WDEN bit) and either the Reset signal(RSTEN bit) 176 * or Interrupt signal(IRQEN) with a specified cycles and the access 177 * key to write to ZMR Register. 178 * 179 * Return: always 0 180 */ 181 static int cdns_wdt_start(struct watchdog_device *wdd) 182 { 183 struct cdns_wdt *wdt = watchdog_get_drvdata(wdd); 184 unsigned int data = 0; 185 unsigned short count; 186 unsigned long clock_f = clk_get_rate(wdt->clk); 187 188 /* 189 * Counter value divisor to obtain the value of 190 * counter reset to be written to control register. 191 */ 192 count = (wdd->timeout * (clock_f / wdt->prescaler)) / 193 CDNS_WDT_COUNTER_VALUE_DIVISOR + 1; 194 195 if (count > CDNS_WDT_COUNTER_MAX) 196 count = CDNS_WDT_COUNTER_MAX; 197 198 spin_lock(&wdt->io_lock); 199 cdns_wdt_writereg(wdt, CDNS_WDT_ZMR_OFFSET, 200 CDNS_WDT_ZMR_ZKEY_VAL); 201 202 count = (count << 2) & CDNS_WDT_CCR_CRV_MASK; 203 204 /* Write counter access key first to be able write to register */ 205 data = count | CDNS_WDT_REGISTER_ACCESS_KEY | wdt->ctrl_clksel; 206 cdns_wdt_writereg(wdt, CDNS_WDT_CCR_OFFSET, data); 207 data = CDNS_WDT_ZMR_WDEN_MASK | CDNS_WDT_ZMR_RSTLEN_16 | 208 CDNS_WDT_ZMR_ZKEY_VAL; 209 210 /* Reset on timeout if specified in device tree. */ 211 if (wdt->rst) { 212 data |= CDNS_WDT_ZMR_RSTEN_MASK; 213 data &= ~CDNS_WDT_ZMR_IRQEN_MASK; 214 } else { 215 data &= ~CDNS_WDT_ZMR_RSTEN_MASK; 216 data |= CDNS_WDT_ZMR_IRQEN_MASK; 217 } 218 cdns_wdt_writereg(wdt, CDNS_WDT_ZMR_OFFSET, data); 219 cdns_wdt_writereg(wdt, CDNS_WDT_RESTART_OFFSET, 220 CDNS_WDT_RESTART_KEY); 221 spin_unlock(&wdt->io_lock); 222 223 return 0; 224 } 225 226 /** 227 * cdns_wdt_settimeout - Set a new timeout value for the watchdog device. 228 * 229 * @wdd: watchdog device 230 * @new_time: new timeout value that needs to be set 231 * Return: 0 on success 232 * 233 * Update the watchdog_device timeout with new value which is used when 234 * cdns_wdt_start is called. 235 */ 236 static int cdns_wdt_settimeout(struct watchdog_device *wdd, 237 unsigned int new_time) 238 { 239 wdd->timeout = new_time; 240 241 return cdns_wdt_start(wdd); 242 } 243 244 /** 245 * cdns_wdt_irq_handler - Notifies of watchdog timeout. 246 * 247 * @irq: interrupt number 248 * @dev_id: pointer to a platform device structure 249 * Return: IRQ_HANDLED 250 * 251 * The handler is invoked when the watchdog times out and a 252 * reset on timeout has not been enabled. 253 */ 254 static irqreturn_t cdns_wdt_irq_handler(int irq, void *dev_id) 255 { 256 struct platform_device *pdev = dev_id; 257 258 dev_info(&pdev->dev, 259 "Watchdog timed out. Internal reset not enabled\n"); 260 261 return IRQ_HANDLED; 262 } 263 264 /* 265 * Info structure used to indicate the features supported by the device 266 * to the upper layers. This is defined in watchdog.h header file. 267 */ 268 static struct watchdog_info cdns_wdt_info = { 269 .identity = "cdns_wdt watchdog", 270 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 271 WDIOF_MAGICCLOSE, 272 }; 273 274 /* Watchdog Core Ops */ 275 static struct watchdog_ops cdns_wdt_ops = { 276 .owner = THIS_MODULE, 277 .start = cdns_wdt_start, 278 .stop = cdns_wdt_stop, 279 .ping = cdns_wdt_reload, 280 .set_timeout = cdns_wdt_settimeout, 281 }; 282 283 /** 284 * cdns_wdt_notify_sys - Notifier for reboot or shutdown. 285 * 286 * @this: handle to notifier block 287 * @code: turn off indicator 288 * @unused: unused 289 * Return: NOTIFY_DONE 290 * 291 * This notifier is invoked whenever the system reboot or shutdown occur 292 * because we need to disable the WDT before system goes down as WDT might 293 * reset on the next boot. 294 */ 295 static int cdns_wdt_notify_sys(struct notifier_block *this, unsigned long code, 296 void *unused) 297 { 298 struct cdns_wdt *wdt = container_of(this, struct cdns_wdt, 299 cdns_wdt_notifier); 300 if (code == SYS_DOWN || code == SYS_HALT) 301 cdns_wdt_stop(&wdt->cdns_wdt_device); 302 303 return NOTIFY_DONE; 304 } 305 306 /************************Platform Operations*****************************/ 307 /** 308 * cdns_wdt_probe - Probe call for the device. 309 * 310 * @pdev: handle to the platform device structure. 311 * Return: 0 on success, negative error otherwise. 312 * 313 * It does all the memory allocation and registration for the device. 314 */ 315 static int cdns_wdt_probe(struct platform_device *pdev) 316 { 317 struct resource *res; 318 int ret, irq; 319 unsigned long clock_f; 320 struct cdns_wdt *wdt; 321 struct watchdog_device *cdns_wdt_device; 322 323 wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); 324 if (!wdt) 325 return -ENOMEM; 326 327 cdns_wdt_device = &wdt->cdns_wdt_device; 328 cdns_wdt_device->info = &cdns_wdt_info; 329 cdns_wdt_device->ops = &cdns_wdt_ops; 330 cdns_wdt_device->timeout = CDNS_WDT_DEFAULT_TIMEOUT; 331 cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT; 332 cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT; 333 334 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 335 wdt->regs = devm_ioremap_resource(&pdev->dev, res); 336 if (IS_ERR(wdt->regs)) 337 return PTR_ERR(wdt->regs); 338 339 /* Register the interrupt */ 340 wdt->rst = of_property_read_bool(pdev->dev.of_node, "reset-on-timeout"); 341 irq = platform_get_irq(pdev, 0); 342 if (!wdt->rst && irq >= 0) { 343 ret = devm_request_irq(&pdev->dev, irq, cdns_wdt_irq_handler, 0, 344 pdev->name, pdev); 345 if (ret) { 346 dev_err(&pdev->dev, 347 "cannot register interrupt handler err=%d\n", 348 ret); 349 return ret; 350 } 351 } 352 353 /* Initialize the members of cdns_wdt structure */ 354 cdns_wdt_device->parent = &pdev->dev; 355 356 ret = watchdog_init_timeout(cdns_wdt_device, wdt_timeout, &pdev->dev); 357 if (ret) { 358 dev_err(&pdev->dev, "unable to set timeout value\n"); 359 return ret; 360 } 361 362 watchdog_set_nowayout(cdns_wdt_device, nowayout); 363 watchdog_set_drvdata(cdns_wdt_device, wdt); 364 365 wdt->clk = devm_clk_get(&pdev->dev, NULL); 366 if (IS_ERR(wdt->clk)) { 367 dev_err(&pdev->dev, "input clock not found\n"); 368 ret = PTR_ERR(wdt->clk); 369 return ret; 370 } 371 372 ret = clk_prepare_enable(wdt->clk); 373 if (ret) { 374 dev_err(&pdev->dev, "unable to enable clock\n"); 375 return ret; 376 } 377 378 clock_f = clk_get_rate(wdt->clk); 379 if (clock_f <= CDNS_WDT_CLK_75MHZ) { 380 wdt->prescaler = CDNS_WDT_PRESCALE_512; 381 wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512; 382 } else { 383 wdt->prescaler = CDNS_WDT_PRESCALE_4096; 384 wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_4096; 385 } 386 387 spin_lock_init(&wdt->io_lock); 388 389 wdt->cdns_wdt_notifier.notifier_call = &cdns_wdt_notify_sys; 390 ret = register_reboot_notifier(&wdt->cdns_wdt_notifier); 391 if (ret != 0) { 392 dev_err(&pdev->dev, "cannot register reboot notifier err=%d)\n", 393 ret); 394 goto err_clk_disable; 395 } 396 397 ret = watchdog_register_device(cdns_wdt_device); 398 if (ret) { 399 dev_err(&pdev->dev, "Failed to register wdt device\n"); 400 goto err_clk_disable; 401 } 402 platform_set_drvdata(pdev, wdt); 403 404 dev_dbg(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n", 405 wdt->regs, cdns_wdt_device->timeout, 406 nowayout ? ", nowayout" : ""); 407 408 return 0; 409 410 err_clk_disable: 411 clk_disable_unprepare(wdt->clk); 412 413 return ret; 414 } 415 416 /** 417 * cdns_wdt_remove - Probe call for the device. 418 * 419 * @pdev: handle to the platform device structure. 420 * Return: 0 on success, otherwise negative error. 421 * 422 * Unregister the device after releasing the resources. 423 */ 424 static int cdns_wdt_remove(struct platform_device *pdev) 425 { 426 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 427 428 cdns_wdt_stop(&wdt->cdns_wdt_device); 429 watchdog_unregister_device(&wdt->cdns_wdt_device); 430 unregister_reboot_notifier(&wdt->cdns_wdt_notifier); 431 clk_disable_unprepare(wdt->clk); 432 433 return 0; 434 } 435 436 /** 437 * cdns_wdt_shutdown - Stop the device. 438 * 439 * @pdev: handle to the platform structure. 440 * 441 */ 442 static void cdns_wdt_shutdown(struct platform_device *pdev) 443 { 444 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 445 446 cdns_wdt_stop(&wdt->cdns_wdt_device); 447 clk_disable_unprepare(wdt->clk); 448 } 449 450 /** 451 * cdns_wdt_suspend - Stop the device. 452 * 453 * @dev: handle to the device structure. 454 * Return: 0 always. 455 */ 456 static int __maybe_unused cdns_wdt_suspend(struct device *dev) 457 { 458 struct platform_device *pdev = container_of(dev, 459 struct platform_device, dev); 460 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 461 462 cdns_wdt_stop(&wdt->cdns_wdt_device); 463 clk_disable_unprepare(wdt->clk); 464 465 return 0; 466 } 467 468 /** 469 * cdns_wdt_resume - Resume the device. 470 * 471 * @dev: handle to the device structure. 472 * Return: 0 on success, errno otherwise. 473 */ 474 static int __maybe_unused cdns_wdt_resume(struct device *dev) 475 { 476 int ret; 477 struct platform_device *pdev = container_of(dev, 478 struct platform_device, dev); 479 struct cdns_wdt *wdt = platform_get_drvdata(pdev); 480 481 ret = clk_prepare_enable(wdt->clk); 482 if (ret) { 483 dev_err(dev, "unable to enable clock\n"); 484 return ret; 485 } 486 cdns_wdt_start(&wdt->cdns_wdt_device); 487 488 return 0; 489 } 490 491 static SIMPLE_DEV_PM_OPS(cdns_wdt_pm_ops, cdns_wdt_suspend, cdns_wdt_resume); 492 493 static struct of_device_id cdns_wdt_of_match[] = { 494 { .compatible = "cdns,wdt-r1p2", }, 495 { /* end of table */ } 496 }; 497 MODULE_DEVICE_TABLE(of, cdns_wdt_of_match); 498 499 /* Driver Structure */ 500 static struct platform_driver cdns_wdt_driver = { 501 .probe = cdns_wdt_probe, 502 .remove = cdns_wdt_remove, 503 .shutdown = cdns_wdt_shutdown, 504 .driver = { 505 .name = "cdns-wdt", 506 .owner = THIS_MODULE, 507 .of_match_table = cdns_wdt_of_match, 508 .pm = &cdns_wdt_pm_ops, 509 }, 510 }; 511 512 module_platform_driver(cdns_wdt_driver); 513 514 MODULE_AUTHOR("Xilinx, Inc."); 515 MODULE_DESCRIPTION("Watchdog driver for Cadence WDT"); 516 MODULE_LICENSE("GPL"); 517