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