1 /* 2 * ACPI Hardware Watchdog (WDAT) driver. 3 * 4 * Copyright (C) 2016, Intel Corporation 5 * Author: Mika Westerberg <mika.westerberg@linux.intel.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12 #include <linux/acpi.h> 13 #include <linux/ioport.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/pm.h> 17 #include <linux/watchdog.h> 18 19 #define MAX_WDAT_ACTIONS ACPI_WDAT_ACTION_RESERVED 20 21 /** 22 * struct wdat_instruction - Single ACPI WDAT instruction 23 * @entry: Copy of the ACPI table instruction 24 * @reg: Register the instruction is accessing 25 * @node: Next instruction in action sequence 26 */ 27 struct wdat_instruction { 28 struct acpi_wdat_entry entry; 29 void __iomem *reg; 30 struct list_head node; 31 }; 32 33 /** 34 * struct wdat_wdt - ACPI WDAT watchdog device 35 * @pdev: Parent platform device 36 * @wdd: Watchdog core device 37 * @period: How long is one watchdog period in ms 38 * @stopped_in_sleep: Is this watchdog stopped by the firmware in S1-S5 39 * @stopped: Was the watchdog stopped by the driver in suspend 40 * @actions: An array of instruction lists indexed by an action number from 41 * the WDAT table. There can be %NULL entries for not implemented 42 * actions. 43 */ 44 struct wdat_wdt { 45 struct platform_device *pdev; 46 struct watchdog_device wdd; 47 unsigned int period; 48 bool stopped_in_sleep; 49 bool stopped; 50 struct list_head *instructions[MAX_WDAT_ACTIONS]; 51 }; 52 53 #define to_wdat_wdt(wdd) container_of(wdd, struct wdat_wdt, wdd) 54 55 static bool nowayout = WATCHDOG_NOWAYOUT; 56 module_param(nowayout, bool, 0); 57 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 58 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 59 60 static int wdat_wdt_read(struct wdat_wdt *wdat, 61 const struct wdat_instruction *instr, u32 *value) 62 { 63 const struct acpi_generic_address *gas = &instr->entry.register_region; 64 65 switch (gas->access_width) { 66 case 1: 67 *value = ioread8(instr->reg); 68 break; 69 case 2: 70 *value = ioread16(instr->reg); 71 break; 72 case 3: 73 *value = ioread32(instr->reg); 74 break; 75 default: 76 return -EINVAL; 77 } 78 79 dev_dbg(&wdat->pdev->dev, "Read %#x from 0x%08llx\n", *value, 80 gas->address); 81 82 return 0; 83 } 84 85 static int wdat_wdt_write(struct wdat_wdt *wdat, 86 const struct wdat_instruction *instr, u32 value) 87 { 88 const struct acpi_generic_address *gas = &instr->entry.register_region; 89 90 switch (gas->access_width) { 91 case 1: 92 iowrite8((u8)value, instr->reg); 93 break; 94 case 2: 95 iowrite16((u16)value, instr->reg); 96 break; 97 case 3: 98 iowrite32(value, instr->reg); 99 break; 100 default: 101 return -EINVAL; 102 } 103 104 dev_dbg(&wdat->pdev->dev, "Wrote %#x to 0x%08llx\n", value, 105 gas->address); 106 107 return 0; 108 } 109 110 static int wdat_wdt_run_action(struct wdat_wdt *wdat, unsigned int action, 111 u32 param, u32 *retval) 112 { 113 struct wdat_instruction *instr; 114 115 if (action >= ARRAY_SIZE(wdat->instructions)) 116 return -EINVAL; 117 118 if (!wdat->instructions[action]) 119 return -EOPNOTSUPP; 120 121 dev_dbg(&wdat->pdev->dev, "Running action %#x\n", action); 122 123 /* Run each instruction sequentially */ 124 list_for_each_entry(instr, wdat->instructions[action], node) { 125 const struct acpi_wdat_entry *entry = &instr->entry; 126 const struct acpi_generic_address *gas; 127 u32 flags, value, mask, x, y; 128 bool preserve; 129 int ret; 130 131 gas = &entry->register_region; 132 133 preserve = entry->instruction & ACPI_WDAT_PRESERVE_REGISTER; 134 flags = entry->instruction & ~ACPI_WDAT_PRESERVE_REGISTER; 135 value = entry->value; 136 mask = entry->mask; 137 138 switch (flags) { 139 case ACPI_WDAT_READ_VALUE: 140 ret = wdat_wdt_read(wdat, instr, &x); 141 if (ret) 142 return ret; 143 x >>= gas->bit_offset; 144 x &= mask; 145 if (retval) 146 *retval = x == value; 147 break; 148 149 case ACPI_WDAT_READ_COUNTDOWN: 150 ret = wdat_wdt_read(wdat, instr, &x); 151 if (ret) 152 return ret; 153 x >>= gas->bit_offset; 154 x &= mask; 155 if (retval) 156 *retval = x; 157 break; 158 159 case ACPI_WDAT_WRITE_VALUE: 160 x = value & mask; 161 x <<= gas->bit_offset; 162 if (preserve) { 163 ret = wdat_wdt_read(wdat, instr, &y); 164 if (ret) 165 return ret; 166 y = y & ~(mask << gas->bit_offset); 167 x |= y; 168 } 169 ret = wdat_wdt_write(wdat, instr, x); 170 if (ret) 171 return ret; 172 break; 173 174 case ACPI_WDAT_WRITE_COUNTDOWN: 175 x = param; 176 x &= mask; 177 x <<= gas->bit_offset; 178 if (preserve) { 179 ret = wdat_wdt_read(wdat, instr, &y); 180 if (ret) 181 return ret; 182 y = y & ~(mask << gas->bit_offset); 183 x |= y; 184 } 185 ret = wdat_wdt_write(wdat, instr, x); 186 if (ret) 187 return ret; 188 break; 189 190 default: 191 dev_err(&wdat->pdev->dev, "Unknown instruction: %u\n", 192 flags); 193 return -EINVAL; 194 } 195 } 196 197 return 0; 198 } 199 200 static int wdat_wdt_enable_reboot(struct wdat_wdt *wdat) 201 { 202 int ret; 203 204 /* 205 * WDAT specification says that the watchdog is required to reboot 206 * the system when it fires. However, it also states that it is 207 * recommeded to make it configurable through hardware register. We 208 * enable reboot now if it is configrable, just in case. 209 */ 210 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_REBOOT, 0, NULL); 211 if (ret && ret != -EOPNOTSUPP) { 212 dev_err(&wdat->pdev->dev, 213 "Failed to enable reboot when watchdog triggers\n"); 214 return ret; 215 } 216 217 return 0; 218 } 219 220 static void wdat_wdt_boot_status(struct wdat_wdt *wdat) 221 { 222 u32 boot_status = 0; 223 int ret; 224 225 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_GET_STATUS, 0, &boot_status); 226 if (ret && ret != -EOPNOTSUPP) { 227 dev_err(&wdat->pdev->dev, "Failed to read boot status\n"); 228 return; 229 } 230 231 if (boot_status) 232 wdat->wdd.bootstatus = WDIOF_CARDRESET; 233 234 /* Clear the boot status in case BIOS did not do it */ 235 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_STATUS, 0, NULL); 236 if (ret && ret != -EOPNOTSUPP) 237 dev_err(&wdat->pdev->dev, "Failed to clear boot status\n"); 238 } 239 240 static void wdat_wdt_set_running(struct wdat_wdt *wdat) 241 { 242 u32 running = 0; 243 int ret; 244 245 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_GET_RUNNING_STATE, 0, 246 &running); 247 if (ret && ret != -EOPNOTSUPP) 248 dev_err(&wdat->pdev->dev, "Failed to read running state\n"); 249 250 if (running) 251 set_bit(WDOG_HW_RUNNING, &wdat->wdd.status); 252 } 253 254 static int wdat_wdt_start(struct watchdog_device *wdd) 255 { 256 return wdat_wdt_run_action(to_wdat_wdt(wdd), 257 ACPI_WDAT_SET_RUNNING_STATE, 0, NULL); 258 } 259 260 static int wdat_wdt_stop(struct watchdog_device *wdd) 261 { 262 return wdat_wdt_run_action(to_wdat_wdt(wdd), 263 ACPI_WDAT_SET_STOPPED_STATE, 0, NULL); 264 } 265 266 static int wdat_wdt_ping(struct watchdog_device *wdd) 267 { 268 return wdat_wdt_run_action(to_wdat_wdt(wdd), ACPI_WDAT_RESET, 0, NULL); 269 } 270 271 static int wdat_wdt_set_timeout(struct watchdog_device *wdd, 272 unsigned int timeout) 273 { 274 struct wdat_wdt *wdat = to_wdat_wdt(wdd); 275 unsigned int periods; 276 int ret; 277 278 periods = timeout * 1000 / wdat->period; 279 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_COUNTDOWN, periods, NULL); 280 if (!ret) 281 wdd->timeout = timeout; 282 return ret; 283 } 284 285 static unsigned int wdat_wdt_get_timeleft(struct watchdog_device *wdd) 286 { 287 struct wdat_wdt *wdat = to_wdat_wdt(wdd); 288 u32 periods = 0; 289 290 wdat_wdt_run_action(wdat, ACPI_WDAT_GET_COUNTDOWN, 0, &periods); 291 return periods * wdat->period / 1000; 292 } 293 294 static const struct watchdog_info wdat_wdt_info = { 295 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 296 .firmware_version = 0, 297 .identity = "wdat_wdt", 298 }; 299 300 static const struct watchdog_ops wdat_wdt_ops = { 301 .owner = THIS_MODULE, 302 .start = wdat_wdt_start, 303 .stop = wdat_wdt_stop, 304 .ping = wdat_wdt_ping, 305 .set_timeout = wdat_wdt_set_timeout, 306 .get_timeleft = wdat_wdt_get_timeleft, 307 }; 308 309 static int wdat_wdt_probe(struct platform_device *pdev) 310 { 311 const struct acpi_wdat_entry *entries; 312 const struct acpi_table_wdat *tbl; 313 struct wdat_wdt *wdat; 314 struct resource *res; 315 void __iomem **regs; 316 acpi_status status; 317 int i, ret; 318 319 status = acpi_get_table(ACPI_SIG_WDAT, 0, 320 (struct acpi_table_header **)&tbl); 321 if (ACPI_FAILURE(status)) 322 return -ENODEV; 323 324 wdat = devm_kzalloc(&pdev->dev, sizeof(*wdat), GFP_KERNEL); 325 if (!wdat) 326 return -ENOMEM; 327 328 regs = devm_kcalloc(&pdev->dev, pdev->num_resources, sizeof(*regs), 329 GFP_KERNEL); 330 if (!regs) 331 return -ENOMEM; 332 333 /* WDAT specification wants to have >= 1ms period */ 334 if (tbl->timer_period < 1) 335 return -EINVAL; 336 if (tbl->min_count > tbl->max_count) 337 return -EINVAL; 338 339 wdat->period = tbl->timer_period; 340 wdat->wdd.min_hw_heartbeat_ms = wdat->period * tbl->min_count; 341 wdat->wdd.max_hw_heartbeat_ms = wdat->period * tbl->max_count; 342 wdat->stopped_in_sleep = tbl->flags & ACPI_WDAT_STOPPED; 343 wdat->wdd.info = &wdat_wdt_info; 344 wdat->wdd.ops = &wdat_wdt_ops; 345 wdat->pdev = pdev; 346 347 /* Request and map all resources */ 348 for (i = 0; i < pdev->num_resources; i++) { 349 void __iomem *reg; 350 351 res = &pdev->resource[i]; 352 if (resource_type(res) == IORESOURCE_MEM) { 353 reg = devm_ioremap_resource(&pdev->dev, res); 354 if (IS_ERR(reg)) 355 return PTR_ERR(reg); 356 } else if (resource_type(res) == IORESOURCE_IO) { 357 reg = devm_ioport_map(&pdev->dev, res->start, 1); 358 if (!reg) 359 return -ENOMEM; 360 } else { 361 dev_err(&pdev->dev, "Unsupported resource\n"); 362 return -EINVAL; 363 } 364 365 regs[i] = reg; 366 } 367 368 entries = (struct acpi_wdat_entry *)(tbl + 1); 369 for (i = 0; i < tbl->entries; i++) { 370 const struct acpi_generic_address *gas; 371 struct wdat_instruction *instr; 372 struct list_head *instructions; 373 unsigned int action; 374 struct resource r; 375 int j; 376 377 action = entries[i].action; 378 if (action >= MAX_WDAT_ACTIONS) { 379 dev_dbg(&pdev->dev, "Skipping unknown action: %u\n", 380 action); 381 continue; 382 } 383 384 instr = devm_kzalloc(&pdev->dev, sizeof(*instr), GFP_KERNEL); 385 if (!instr) 386 return -ENOMEM; 387 388 INIT_LIST_HEAD(&instr->node); 389 instr->entry = entries[i]; 390 391 gas = &entries[i].register_region; 392 393 memset(&r, 0, sizeof(r)); 394 r.start = gas->address; 395 r.end = r.start + gas->access_width - 1; 396 if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 397 r.flags = IORESOURCE_MEM; 398 } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { 399 r.flags = IORESOURCE_IO; 400 } else { 401 dev_dbg(&pdev->dev, "Unsupported address space: %d\n", 402 gas->space_id); 403 continue; 404 } 405 406 /* Find the matching resource */ 407 for (j = 0; j < pdev->num_resources; j++) { 408 res = &pdev->resource[j]; 409 if (resource_contains(res, &r)) { 410 instr->reg = regs[j] + r.start - res->start; 411 break; 412 } 413 } 414 415 if (!instr->reg) { 416 dev_err(&pdev->dev, "I/O resource not found\n"); 417 return -EINVAL; 418 } 419 420 instructions = wdat->instructions[action]; 421 if (!instructions) { 422 instructions = devm_kzalloc(&pdev->dev, 423 sizeof(*instructions), GFP_KERNEL); 424 if (!instructions) 425 return -ENOMEM; 426 427 INIT_LIST_HEAD(instructions); 428 wdat->instructions[action] = instructions; 429 } 430 431 list_add_tail(&instr->node, instructions); 432 } 433 434 wdat_wdt_boot_status(wdat); 435 wdat_wdt_set_running(wdat); 436 437 ret = wdat_wdt_enable_reboot(wdat); 438 if (ret) 439 return ret; 440 441 platform_set_drvdata(pdev, wdat); 442 443 watchdog_set_nowayout(&wdat->wdd, nowayout); 444 return devm_watchdog_register_device(&pdev->dev, &wdat->wdd); 445 } 446 447 #ifdef CONFIG_PM_SLEEP 448 static int wdat_wdt_suspend_noirq(struct device *dev) 449 { 450 struct platform_device *pdev = to_platform_device(dev); 451 struct wdat_wdt *wdat = platform_get_drvdata(pdev); 452 int ret; 453 454 if (!watchdog_active(&wdat->wdd)) 455 return 0; 456 457 /* 458 * We need to stop the watchdog if firmare is not doing it or if we 459 * are going suspend to idle (where firmware is not involved). If 460 * firmware is stopping the watchdog we kick it here one more time 461 * to give it some time. 462 */ 463 wdat->stopped = false; 464 if (acpi_target_system_state() == ACPI_STATE_S0 || 465 !wdat->stopped_in_sleep) { 466 ret = wdat_wdt_stop(&wdat->wdd); 467 if (!ret) 468 wdat->stopped = true; 469 } else { 470 ret = wdat_wdt_ping(&wdat->wdd); 471 } 472 473 return ret; 474 } 475 476 static int wdat_wdt_resume_noirq(struct device *dev) 477 { 478 struct platform_device *pdev = to_platform_device(dev); 479 struct wdat_wdt *wdat = platform_get_drvdata(pdev); 480 int ret; 481 482 if (!watchdog_active(&wdat->wdd)) 483 return 0; 484 485 if (!wdat->stopped) { 486 /* 487 * Looks like the boot firmware reinitializes the watchdog 488 * before it hands off to the OS on resume from sleep so we 489 * stop and reprogram the watchdog here. 490 */ 491 ret = wdat_wdt_stop(&wdat->wdd); 492 if (ret) 493 return ret; 494 495 ret = wdat_wdt_set_timeout(&wdat->wdd, wdat->wdd.timeout); 496 if (ret) 497 return ret; 498 499 ret = wdat_wdt_enable_reboot(wdat); 500 if (ret) 501 return ret; 502 503 ret = wdat_wdt_ping(&wdat->wdd); 504 if (ret) 505 return ret; 506 } 507 508 return wdat_wdt_start(&wdat->wdd); 509 } 510 #endif 511 512 static const struct dev_pm_ops wdat_wdt_pm_ops = { 513 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(wdat_wdt_suspend_noirq, 514 wdat_wdt_resume_noirq) 515 }; 516 517 static struct platform_driver wdat_wdt_driver = { 518 .probe = wdat_wdt_probe, 519 .driver = { 520 .name = "wdat_wdt", 521 .pm = &wdat_wdt_pm_ops, 522 }, 523 }; 524 525 module_platform_driver(wdat_wdt_driver); 526 527 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 528 MODULE_DESCRIPTION("ACPI Hardware Watchdog (WDAT) driver"); 529 MODULE_LICENSE("GPL v2"); 530 MODULE_ALIAS("platform:wdat_wdt"); 531