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_CURRENT_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 struct device *dev = &pdev->dev; 312 const struct acpi_wdat_entry *entries; 313 const struct acpi_table_wdat *tbl; 314 struct wdat_wdt *wdat; 315 struct resource *res; 316 void __iomem **regs; 317 acpi_status status; 318 int i, ret; 319 320 status = acpi_get_table(ACPI_SIG_WDAT, 0, 321 (struct acpi_table_header **)&tbl); 322 if (ACPI_FAILURE(status)) 323 return -ENODEV; 324 325 wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); 326 if (!wdat) 327 return -ENOMEM; 328 329 regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), 330 GFP_KERNEL); 331 if (!regs) 332 return -ENOMEM; 333 334 /* WDAT specification wants to have >= 1ms period */ 335 if (tbl->timer_period < 1) 336 return -EINVAL; 337 if (tbl->min_count > tbl->max_count) 338 return -EINVAL; 339 340 wdat->period = tbl->timer_period; 341 wdat->wdd.min_hw_heartbeat_ms = wdat->period * tbl->min_count; 342 wdat->wdd.max_hw_heartbeat_ms = wdat->period * tbl->max_count; 343 wdat->stopped_in_sleep = tbl->flags & ACPI_WDAT_STOPPED; 344 wdat->wdd.info = &wdat_wdt_info; 345 wdat->wdd.ops = &wdat_wdt_ops; 346 wdat->pdev = pdev; 347 348 /* Request and map all resources */ 349 for (i = 0; i < pdev->num_resources; i++) { 350 void __iomem *reg; 351 352 res = &pdev->resource[i]; 353 if (resource_type(res) == IORESOURCE_MEM) { 354 reg = devm_ioremap_resource(dev, res); 355 if (IS_ERR(reg)) 356 return PTR_ERR(reg); 357 } else if (resource_type(res) == IORESOURCE_IO) { 358 reg = devm_ioport_map(dev, res->start, 1); 359 if (!reg) 360 return -ENOMEM; 361 } else { 362 dev_err(dev, "Unsupported resource\n"); 363 return -EINVAL; 364 } 365 366 regs[i] = reg; 367 } 368 369 entries = (struct acpi_wdat_entry *)(tbl + 1); 370 for (i = 0; i < tbl->entries; i++) { 371 const struct acpi_generic_address *gas; 372 struct wdat_instruction *instr; 373 struct list_head *instructions; 374 unsigned int action; 375 struct resource r; 376 int j; 377 378 action = entries[i].action; 379 if (action >= MAX_WDAT_ACTIONS) { 380 dev_dbg(dev, "Skipping unknown action: %u\n", action); 381 continue; 382 } 383 384 instr = devm_kzalloc(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(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(dev, "I/O resource not found\n"); 417 return -EINVAL; 418 } 419 420 instructions = wdat->instructions[action]; 421 if (!instructions) { 422 instructions = devm_kzalloc(dev, 423 sizeof(*instructions), 424 GFP_KERNEL); 425 if (!instructions) 426 return -ENOMEM; 427 428 INIT_LIST_HEAD(instructions); 429 wdat->instructions[action] = instructions; 430 } 431 432 list_add_tail(&instr->node, instructions); 433 } 434 435 wdat_wdt_boot_status(wdat); 436 wdat_wdt_set_running(wdat); 437 438 ret = wdat_wdt_enable_reboot(wdat); 439 if (ret) 440 return ret; 441 442 platform_set_drvdata(pdev, wdat); 443 444 watchdog_set_nowayout(&wdat->wdd, nowayout); 445 return devm_watchdog_register_device(dev, &wdat->wdd); 446 } 447 448 #ifdef CONFIG_PM_SLEEP 449 static int wdat_wdt_suspend_noirq(struct device *dev) 450 { 451 struct wdat_wdt *wdat = dev_get_drvdata(dev); 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 wdat_wdt *wdat = dev_get_drvdata(dev); 479 int ret; 480 481 if (!watchdog_active(&wdat->wdd)) 482 return 0; 483 484 if (!wdat->stopped) { 485 /* 486 * Looks like the boot firmware reinitializes the watchdog 487 * before it hands off to the OS on resume from sleep so we 488 * stop and reprogram the watchdog here. 489 */ 490 ret = wdat_wdt_stop(&wdat->wdd); 491 if (ret) 492 return ret; 493 494 ret = wdat_wdt_set_timeout(&wdat->wdd, wdat->wdd.timeout); 495 if (ret) 496 return ret; 497 498 ret = wdat_wdt_enable_reboot(wdat); 499 if (ret) 500 return ret; 501 502 ret = wdat_wdt_ping(&wdat->wdd); 503 if (ret) 504 return ret; 505 } 506 507 return wdat_wdt_start(&wdat->wdd); 508 } 509 #endif 510 511 static const struct dev_pm_ops wdat_wdt_pm_ops = { 512 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(wdat_wdt_suspend_noirq, 513 wdat_wdt_resume_noirq) 514 }; 515 516 static struct platform_driver wdat_wdt_driver = { 517 .probe = wdat_wdt_probe, 518 .driver = { 519 .name = "wdat_wdt", 520 .pm = &wdat_wdt_pm_ops, 521 }, 522 }; 523 524 module_platform_driver(wdat_wdt_driver); 525 526 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 527 MODULE_DESCRIPTION("ACPI Hardware Watchdog (WDAT) driver"); 528 MODULE_LICENSE("GPL v2"); 529 MODULE_ALIAS("platform:wdat_wdt"); 530