1/* 2 * coh901327_wdt.c 3 * 4 * Copyright (C) 2008-2009 ST-Ericsson AB 5 * License terms: GNU General Public License (GPL) version 2 6 * Watchdog driver for the ST-Ericsson AB COH 901 327 IP core 7 * Author: Linus Walleij <linus.walleij@stericsson.com> 8 */ 9#include <linux/module.h> 10#include <linux/types.h> 11#include <linux/watchdog.h> 12#include <linux/interrupt.h> 13#include <linux/pm.h> 14#include <linux/platform_device.h> 15#include <linux/io.h> 16#include <linux/bitops.h> 17#include <linux/clk.h> 18#include <linux/delay.h> 19#include <linux/err.h> 20 21#define DRV_NAME "WDOG COH 901 327" 22 23/* 24 * COH 901 327 register definitions 25 */ 26 27/* WDOG_FEED Register 32bit (-/W) */ 28#define U300_WDOG_FR 0x00 29#define U300_WDOG_FR_FEED_RESTART_TIMER 0xFEEDU 30/* WDOG_TIMEOUT Register 32bit (R/W) */ 31#define U300_WDOG_TR 0x04 32#define U300_WDOG_TR_TIMEOUT_MASK 0x7FFFU 33/* WDOG_DISABLE1 Register 32bit (-/W) */ 34#define U300_WDOG_D1R 0x08 35#define U300_WDOG_D1R_DISABLE1_DISABLE_TIMER 0x2BADU 36/* WDOG_DISABLE2 Register 32bit (R/W) */ 37#define U300_WDOG_D2R 0x0C 38#define U300_WDOG_D2R_DISABLE2_DISABLE_TIMER 0xCAFEU 39#define U300_WDOG_D2R_DISABLE_STATUS_DISABLED 0xDABEU 40#define U300_WDOG_D2R_DISABLE_STATUS_ENABLED 0x0000U 41/* WDOG_STATUS Register 32bit (R/W) */ 42#define U300_WDOG_SR 0x10 43#define U300_WDOG_SR_STATUS_TIMED_OUT 0xCFE8U 44#define U300_WDOG_SR_STATUS_NORMAL 0x0000U 45#define U300_WDOG_SR_RESET_STATUS_RESET 0xE8B4U 46/* WDOG_COUNT Register 32bit (R/-) */ 47#define U300_WDOG_CR 0x14 48#define U300_WDOG_CR_VALID_IND 0x8000U 49#define U300_WDOG_CR_VALID_STABLE 0x0000U 50#define U300_WDOG_CR_COUNT_VALUE_MASK 0x7FFFU 51/* WDOG_JTAGOVR Register 32bit (R/W) */ 52#define U300_WDOG_JOR 0x18 53#define U300_WDOG_JOR_JTAG_MODE_IND 0x0002U 54#define U300_WDOG_JOR_JTAG_WATCHDOG_ENABLE 0x0001U 55/* WDOG_RESTART Register 32bit (-/W) */ 56#define U300_WDOG_RR 0x1C 57#define U300_WDOG_RR_RESTART_VALUE_RESUME 0xACEDU 58/* WDOG_IRQ_EVENT Register 32bit (R/W) */ 59#define U300_WDOG_IER 0x20 60#define U300_WDOG_IER_WILL_BARK_IRQ_EVENT_IND 0x0001U 61#define U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE 0x0001U 62/* WDOG_IRQ_MASK Register 32bit (R/W) */ 63#define U300_WDOG_IMR 0x24 64#define U300_WDOG_IMR_WILL_BARK_IRQ_ENABLE 0x0001U 65/* WDOG_IRQ_FORCE Register 32bit (R/W) */ 66#define U300_WDOG_IFR 0x28 67#define U300_WDOG_IFR_WILL_BARK_IRQ_FORCE_ENABLE 0x0001U 68 69/* Default timeout in seconds = 1 minute */ 70static unsigned int margin = 60; 71static resource_size_t phybase; 72static resource_size_t physize; 73static int irq; 74static void __iomem *virtbase; 75static struct device *parent; 76 77/* 78 * The watchdog block is of course always clocked, the 79 * clk_enable()/clk_disable() calls are mainly for performing reference 80 * counting higher up in the clock hierarchy. 81 */ 82static struct clk *clk; 83 84/* 85 * Enabling and disabling functions. 86 */ 87static void coh901327_enable(u16 timeout) 88{ 89 u16 val; 90 unsigned long freq; 91 unsigned long delay_ns; 92 93 clk_enable(clk); 94 /* Restart timer if it is disabled */ 95 val = readw(virtbase + U300_WDOG_D2R); 96 if (val == U300_WDOG_D2R_DISABLE_STATUS_DISABLED) 97 writew(U300_WDOG_RR_RESTART_VALUE_RESUME, 98 virtbase + U300_WDOG_RR); 99 /* Acknowledge any pending interrupt so it doesn't just fire off */ 100 writew(U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE, 101 virtbase + U300_WDOG_IER); 102 /* 103 * The interrupt is cleared in the 32 kHz clock domain. 104 * Wait 3 32 kHz cycles for it to take effect 105 */ 106 freq = clk_get_rate(clk); 107 delay_ns = DIV_ROUND_UP(1000000000, freq); /* Freq to ns and round up */ 108 delay_ns = 3 * delay_ns; /* Wait 3 cycles */ 109 ndelay(delay_ns); 110 /* Enable the watchdog interrupt */ 111 writew(U300_WDOG_IMR_WILL_BARK_IRQ_ENABLE, virtbase + U300_WDOG_IMR); 112 /* Activate the watchdog timer */ 113 writew(timeout, virtbase + U300_WDOG_TR); 114 /* Start the watchdog timer */ 115 writew(U300_WDOG_FR_FEED_RESTART_TIMER, virtbase + U300_WDOG_FR); 116 /* 117 * Extra read so that this change propagate in the watchdog. 118 */ 119 (void) readw(virtbase + U300_WDOG_CR); 120 val = readw(virtbase + U300_WDOG_D2R); 121 clk_disable(clk); 122 if (val != U300_WDOG_D2R_DISABLE_STATUS_ENABLED) 123 dev_err(parent, 124 "%s(): watchdog not enabled! D2R value %04x\n", 125 __func__, val); 126} 127 128static void coh901327_disable(void) 129{ 130 u16 val; 131 132 clk_enable(clk); 133 /* Disable the watchdog interrupt if it is active */ 134 writew(0x0000U, virtbase + U300_WDOG_IMR); 135 /* If the watchdog is currently enabled, attempt to disable it */ 136 val = readw(virtbase + U300_WDOG_D2R); 137 if (val != U300_WDOG_D2R_DISABLE_STATUS_DISABLED) { 138 writew(U300_WDOG_D1R_DISABLE1_DISABLE_TIMER, 139 virtbase + U300_WDOG_D1R); 140 writew(U300_WDOG_D2R_DISABLE2_DISABLE_TIMER, 141 virtbase + U300_WDOG_D2R); 142 /* Write this twice (else problems occur) */ 143 writew(U300_WDOG_D2R_DISABLE2_DISABLE_TIMER, 144 virtbase + U300_WDOG_D2R); 145 } 146 val = readw(virtbase + U300_WDOG_D2R); 147 clk_disable(clk); 148 if (val != U300_WDOG_D2R_DISABLE_STATUS_DISABLED) 149 dev_err(parent, 150 "%s(): watchdog not disabled! D2R value %04x\n", 151 __func__, val); 152} 153 154static int coh901327_start(struct watchdog_device *wdt_dev) 155{ 156 coh901327_enable(wdt_dev->timeout * 100); 157 return 0; 158} 159 160static int coh901327_stop(struct watchdog_device *wdt_dev) 161{ 162 coh901327_disable(); 163 return 0; 164} 165 166static int coh901327_ping(struct watchdog_device *wdd) 167{ 168 clk_enable(clk); 169 /* Feed the watchdog */ 170 writew(U300_WDOG_FR_FEED_RESTART_TIMER, 171 virtbase + U300_WDOG_FR); 172 clk_disable(clk); 173 return 0; 174} 175 176static int coh901327_settimeout(struct watchdog_device *wdt_dev, 177 unsigned int time) 178{ 179 wdt_dev->timeout = time; 180 clk_enable(clk); 181 /* Set new timeout value */ 182 writew(time * 100, virtbase + U300_WDOG_TR); 183 /* Feed the dog */ 184 writew(U300_WDOG_FR_FEED_RESTART_TIMER, 185 virtbase + U300_WDOG_FR); 186 clk_disable(clk); 187 return 0; 188} 189 190static unsigned int coh901327_gettimeleft(struct watchdog_device *wdt_dev) 191{ 192 u16 val; 193 194 clk_enable(clk); 195 /* Read repeatedly until the value is stable! */ 196 val = readw(virtbase + U300_WDOG_CR); 197 while (val & U300_WDOG_CR_VALID_IND) 198 val = readw(virtbase + U300_WDOG_CR); 199 val &= U300_WDOG_CR_COUNT_VALUE_MASK; 200 clk_disable(clk); 201 if (val != 0) 202 val /= 100; 203 204 return val; 205} 206 207/* 208 * This interrupt occurs 10 ms before the watchdog WILL bark. 209 */ 210static irqreturn_t coh901327_interrupt(int irq, void *data) 211{ 212 u16 val; 213 214 /* 215 * Ack IRQ? If this occurs we're FUBAR anyway, so 216 * just acknowledge, disable the interrupt and await the imminent end. 217 * If you at some point need a host of callbacks to be called 218 * when the system is about to watchdog-reset, add them here! 219 * 220 * NOTE: on future versions of this IP-block, it will be possible 221 * to prevent a watchdog reset by feeding the watchdog at this 222 * point. 223 */ 224 clk_enable(clk); 225 val = readw(virtbase + U300_WDOG_IER); 226 if (val == U300_WDOG_IER_WILL_BARK_IRQ_EVENT_IND) 227 writew(U300_WDOG_IER_WILL_BARK_IRQ_ACK_ENABLE, 228 virtbase + U300_WDOG_IER); 229 writew(0x0000U, virtbase + U300_WDOG_IMR); 230 clk_disable(clk); 231 dev_crit(parent, "watchdog is barking!\n"); 232 return IRQ_HANDLED; 233} 234 235static const struct watchdog_info coh901327_ident = { 236 .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 237 .identity = DRV_NAME, 238}; 239 240static struct watchdog_ops coh901327_ops = { 241 .owner = THIS_MODULE, 242 .start = coh901327_start, 243 .stop = coh901327_stop, 244 .ping = coh901327_ping, 245 .set_timeout = coh901327_settimeout, 246 .get_timeleft = coh901327_gettimeleft, 247}; 248 249static struct watchdog_device coh901327_wdt = { 250 .info = &coh901327_ident, 251 .ops = &coh901327_ops, 252 /* 253 * Max timeout is 327 since the 10ms 254 * timeout register is max 255 * 0x7FFF = 327670ms ~= 327s. 256 */ 257 .min_timeout = 0, 258 .max_timeout = 327, 259}; 260 261static int __exit coh901327_remove(struct platform_device *pdev) 262{ 263 watchdog_unregister_device(&coh901327_wdt); 264 coh901327_disable(); 265 free_irq(irq, pdev); 266 clk_unprepare(clk); 267 clk_put(clk); 268 iounmap(virtbase); 269 release_mem_region(phybase, physize); 270 return 0; 271} 272 273static int __init coh901327_probe(struct platform_device *pdev) 274{ 275 int ret; 276 u16 val; 277 struct resource *res; 278 279 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 280 if (!res) 281 return -ENOENT; 282 283 parent = &pdev->dev; 284 physize = resource_size(res); 285 phybase = res->start; 286 287 if (request_mem_region(phybase, physize, DRV_NAME) == NULL) { 288 ret = -EBUSY; 289 goto out; 290 } 291 292 virtbase = ioremap(phybase, physize); 293 if (!virtbase) { 294 ret = -ENOMEM; 295 goto out_no_remap; 296 } 297 298 clk = clk_get(&pdev->dev, NULL); 299 if (IS_ERR(clk)) { 300 ret = PTR_ERR(clk); 301 dev_err(&pdev->dev, "could not get clock\n"); 302 goto out_no_clk; 303 } 304 ret = clk_prepare_enable(clk); 305 if (ret) { 306 dev_err(&pdev->dev, "could not prepare and enable clock\n"); 307 goto out_no_clk_enable; 308 } 309 310 val = readw(virtbase + U300_WDOG_SR); 311 switch (val) { 312 case U300_WDOG_SR_STATUS_TIMED_OUT: 313 dev_info(&pdev->dev, 314 "watchdog timed out since last chip reset!\n"); 315 coh901327_wdt.bootstatus |= WDIOF_CARDRESET; 316 /* Status will be cleared below */ 317 break; 318 case U300_WDOG_SR_STATUS_NORMAL: 319 dev_info(&pdev->dev, 320 "in normal status, no timeouts have occurred.\n"); 321 break; 322 default: 323 dev_info(&pdev->dev, 324 "contains an illegal status code (%08x)\n", val); 325 break; 326 } 327 328 val = readw(virtbase + U300_WDOG_D2R); 329 switch (val) { 330 case U300_WDOG_D2R_DISABLE_STATUS_DISABLED: 331 dev_info(&pdev->dev, "currently disabled.\n"); 332 break; 333 case U300_WDOG_D2R_DISABLE_STATUS_ENABLED: 334 dev_info(&pdev->dev, 335 "currently enabled! (disabling it now)\n"); 336 coh901327_disable(); 337 break; 338 default: 339 dev_err(&pdev->dev, 340 "contains an illegal enable/disable code (%08x)\n", 341 val); 342 break; 343 } 344 345 /* Reset the watchdog */ 346 writew(U300_WDOG_SR_RESET_STATUS_RESET, virtbase + U300_WDOG_SR); 347 348 irq = platform_get_irq(pdev, 0); 349 if (request_irq(irq, coh901327_interrupt, 0, 350 DRV_NAME " Bark", pdev)) { 351 ret = -EIO; 352 goto out_no_irq; 353 } 354 355 clk_disable(clk); 356 357 ret = watchdog_init_timeout(&coh901327_wdt, margin, &pdev->dev); 358 if (ret < 0) 359 coh901327_wdt.timeout = 60; 360 361 ret = watchdog_register_device(&coh901327_wdt); 362 if (ret == 0) 363 dev_info(&pdev->dev, 364 "initialized. timer margin=%d sec\n", margin); 365 else 366 goto out_no_wdog; 367 368 return 0; 369 370out_no_wdog: 371 free_irq(irq, pdev); 372out_no_irq: 373 clk_disable_unprepare(clk); 374out_no_clk_enable: 375 clk_put(clk); 376out_no_clk: 377 iounmap(virtbase); 378out_no_remap: 379 release_mem_region(phybase, SZ_4K); 380out: 381 return ret; 382} 383 384#ifdef CONFIG_PM 385 386static u16 wdogenablestore; 387static u16 irqmaskstore; 388 389static int coh901327_suspend(struct platform_device *pdev, pm_message_t state) 390{ 391 irqmaskstore = readw(virtbase + U300_WDOG_IMR) & 0x0001U; 392 wdogenablestore = readw(virtbase + U300_WDOG_D2R); 393 /* If watchdog is on, disable it here and now */ 394 if (wdogenablestore == U300_WDOG_D2R_DISABLE_STATUS_ENABLED) 395 coh901327_disable(); 396 return 0; 397} 398 399static int coh901327_resume(struct platform_device *pdev) 400{ 401 /* Restore the watchdog interrupt */ 402 writew(irqmaskstore, virtbase + U300_WDOG_IMR); 403 if (wdogenablestore == U300_WDOG_D2R_DISABLE_STATUS_ENABLED) { 404 /* Restart the watchdog timer */ 405 writew(U300_WDOG_RR_RESTART_VALUE_RESUME, 406 virtbase + U300_WDOG_RR); 407 writew(U300_WDOG_FR_FEED_RESTART_TIMER, 408 virtbase + U300_WDOG_FR); 409 } 410 return 0; 411} 412#else 413#define coh901327_suspend NULL 414#define coh901327_resume NULL 415#endif 416 417/* 418 * Mistreating the watchdog is the only way to perform a software reset of the 419 * system on EMP platforms. So we implement this and export a symbol for it. 420 */ 421void coh901327_watchdog_reset(void) 422{ 423 /* Enable even if on JTAG too */ 424 writew(U300_WDOG_JOR_JTAG_WATCHDOG_ENABLE, 425 virtbase + U300_WDOG_JOR); 426 /* 427 * Timeout = 5s, we have to wait for the watchdog reset to 428 * actually take place: the watchdog will be reloaded with the 429 * default value immediately, so we HAVE to reboot and get back 430 * into the kernel in 30s, or the device will reboot again! 431 * The boot loader will typically deactivate the watchdog, so we 432 * need time enough for the boot loader to get to the point of 433 * deactivating the watchdog before it is shut down by it. 434 * 435 * NOTE: on future versions of the watchdog, this restriction is 436 * gone: the watchdog will be reloaded with a default value (1 min) 437 * instead of last value, and you can conveniently set the watchdog 438 * timeout to 10ms (value = 1) without any problems. 439 */ 440 coh901327_enable(500); 441 /* Return and await doom */ 442} 443 444static const struct of_device_id coh901327_dt_match[] = { 445 { .compatible = "stericsson,coh901327" }, 446 {}, 447}; 448 449static struct platform_driver coh901327_driver = { 450 .driver = { 451 .name = "coh901327_wdog", 452 .of_match_table = coh901327_dt_match, 453 }, 454 .remove = __exit_p(coh901327_remove), 455 .suspend = coh901327_suspend, 456 .resume = coh901327_resume, 457}; 458 459module_platform_driver_probe(coh901327_driver, coh901327_probe); 460 461MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); 462MODULE_DESCRIPTION("COH 901 327 Watchdog"); 463 464module_param(margin, uint, 0); 465MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); 466 467MODULE_LICENSE("GPL"); 468MODULE_ALIAS("platform:coh901327-watchdog"); 469