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