0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/acpi.h>
0010 #include <linux/ioport.h>
0011 #include <linux/module.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/pm.h>
0014 #include <linux/watchdog.h>
0015
0016 #define MAX_WDAT_ACTIONS ACPI_WDAT_ACTION_RESERVED
0017
0018
0019
0020
0021
0022
0023
0024 struct wdat_instruction {
0025 struct acpi_wdat_entry entry;
0026 void __iomem *reg;
0027 struct list_head node;
0028 };
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 struct wdat_wdt {
0042 struct platform_device *pdev;
0043 struct watchdog_device wdd;
0044 unsigned int period;
0045 bool stopped_in_sleep;
0046 bool stopped;
0047 struct list_head *instructions[MAX_WDAT_ACTIONS];
0048 };
0049
0050 #define to_wdat_wdt(wdd) container_of(wdd, struct wdat_wdt, wdd)
0051
0052 static bool nowayout = WATCHDOG_NOWAYOUT;
0053 module_param(nowayout, bool, 0);
0054 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
0055 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0056
0057 #define WDAT_DEFAULT_TIMEOUT 30
0058
0059 static int timeout = WDAT_DEFAULT_TIMEOUT;
0060 module_param(timeout, int, 0);
0061 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default="
0062 __MODULE_STRING(WDAT_DEFAULT_TIMEOUT) ")");
0063
0064 static int wdat_wdt_read(struct wdat_wdt *wdat,
0065 const struct wdat_instruction *instr, u32 *value)
0066 {
0067 const struct acpi_generic_address *gas = &instr->entry.register_region;
0068
0069 switch (gas->access_width) {
0070 case 1:
0071 *value = ioread8(instr->reg);
0072 break;
0073 case 2:
0074 *value = ioread16(instr->reg);
0075 break;
0076 case 3:
0077 *value = ioread32(instr->reg);
0078 break;
0079 default:
0080 return -EINVAL;
0081 }
0082
0083 dev_dbg(&wdat->pdev->dev, "Read %#x from 0x%08llx\n", *value,
0084 gas->address);
0085
0086 return 0;
0087 }
0088
0089 static int wdat_wdt_write(struct wdat_wdt *wdat,
0090 const struct wdat_instruction *instr, u32 value)
0091 {
0092 const struct acpi_generic_address *gas = &instr->entry.register_region;
0093
0094 switch (gas->access_width) {
0095 case 1:
0096 iowrite8((u8)value, instr->reg);
0097 break;
0098 case 2:
0099 iowrite16((u16)value, instr->reg);
0100 break;
0101 case 3:
0102 iowrite32(value, instr->reg);
0103 break;
0104 default:
0105 return -EINVAL;
0106 }
0107
0108 dev_dbg(&wdat->pdev->dev, "Wrote %#x to 0x%08llx\n", value,
0109 gas->address);
0110
0111 return 0;
0112 }
0113
0114 static int wdat_wdt_run_action(struct wdat_wdt *wdat, unsigned int action,
0115 u32 param, u32 *retval)
0116 {
0117 struct wdat_instruction *instr;
0118
0119 if (action >= ARRAY_SIZE(wdat->instructions))
0120 return -EINVAL;
0121
0122 if (!wdat->instructions[action])
0123 return -EOPNOTSUPP;
0124
0125 dev_dbg(&wdat->pdev->dev, "Running action %#x\n", action);
0126
0127
0128 list_for_each_entry(instr, wdat->instructions[action], node) {
0129 const struct acpi_wdat_entry *entry = &instr->entry;
0130 const struct acpi_generic_address *gas;
0131 u32 flags, value, mask, x, y;
0132 bool preserve;
0133 int ret;
0134
0135 gas = &entry->register_region;
0136
0137 preserve = entry->instruction & ACPI_WDAT_PRESERVE_REGISTER;
0138 flags = entry->instruction & ~ACPI_WDAT_PRESERVE_REGISTER;
0139 value = entry->value;
0140 mask = entry->mask;
0141
0142 switch (flags) {
0143 case ACPI_WDAT_READ_VALUE:
0144 ret = wdat_wdt_read(wdat, instr, &x);
0145 if (ret)
0146 return ret;
0147 x >>= gas->bit_offset;
0148 x &= mask;
0149 if (retval)
0150 *retval = x == value;
0151 break;
0152
0153 case ACPI_WDAT_READ_COUNTDOWN:
0154 ret = wdat_wdt_read(wdat, instr, &x);
0155 if (ret)
0156 return ret;
0157 x >>= gas->bit_offset;
0158 x &= mask;
0159 if (retval)
0160 *retval = x;
0161 break;
0162
0163 case ACPI_WDAT_WRITE_VALUE:
0164 x = value & mask;
0165 x <<= gas->bit_offset;
0166 if (preserve) {
0167 ret = wdat_wdt_read(wdat, instr, &y);
0168 if (ret)
0169 return ret;
0170 y = y & ~(mask << gas->bit_offset);
0171 x |= y;
0172 }
0173 ret = wdat_wdt_write(wdat, instr, x);
0174 if (ret)
0175 return ret;
0176 break;
0177
0178 case ACPI_WDAT_WRITE_COUNTDOWN:
0179 x = param;
0180 x &= mask;
0181 x <<= gas->bit_offset;
0182 if (preserve) {
0183 ret = wdat_wdt_read(wdat, instr, &y);
0184 if (ret)
0185 return ret;
0186 y = y & ~(mask << gas->bit_offset);
0187 x |= y;
0188 }
0189 ret = wdat_wdt_write(wdat, instr, x);
0190 if (ret)
0191 return ret;
0192 break;
0193
0194 default:
0195 dev_err(&wdat->pdev->dev, "Unknown instruction: %u\n",
0196 flags);
0197 return -EINVAL;
0198 }
0199 }
0200
0201 return 0;
0202 }
0203
0204 static int wdat_wdt_enable_reboot(struct wdat_wdt *wdat)
0205 {
0206 int ret;
0207
0208
0209
0210
0211
0212
0213
0214 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_REBOOT, 0, NULL);
0215 if (ret && ret != -EOPNOTSUPP) {
0216 dev_err(&wdat->pdev->dev,
0217 "Failed to enable reboot when watchdog triggers\n");
0218 return ret;
0219 }
0220
0221 return 0;
0222 }
0223
0224 static void wdat_wdt_boot_status(struct wdat_wdt *wdat)
0225 {
0226 u32 boot_status = 0;
0227 int ret;
0228
0229 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_GET_STATUS, 0, &boot_status);
0230 if (ret && ret != -EOPNOTSUPP) {
0231 dev_err(&wdat->pdev->dev, "Failed to read boot status\n");
0232 return;
0233 }
0234
0235 if (boot_status)
0236 wdat->wdd.bootstatus = WDIOF_CARDRESET;
0237
0238
0239 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_STATUS, 0, NULL);
0240 if (ret && ret != -EOPNOTSUPP)
0241 dev_err(&wdat->pdev->dev, "Failed to clear boot status\n");
0242 }
0243
0244 static void wdat_wdt_set_running(struct wdat_wdt *wdat)
0245 {
0246 u32 running = 0;
0247 int ret;
0248
0249 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_GET_RUNNING_STATE, 0,
0250 &running);
0251 if (ret && ret != -EOPNOTSUPP)
0252 dev_err(&wdat->pdev->dev, "Failed to read running state\n");
0253
0254 if (running)
0255 set_bit(WDOG_HW_RUNNING, &wdat->wdd.status);
0256 }
0257
0258 static int wdat_wdt_start(struct watchdog_device *wdd)
0259 {
0260 return wdat_wdt_run_action(to_wdat_wdt(wdd),
0261 ACPI_WDAT_SET_RUNNING_STATE, 0, NULL);
0262 }
0263
0264 static int wdat_wdt_stop(struct watchdog_device *wdd)
0265 {
0266 return wdat_wdt_run_action(to_wdat_wdt(wdd),
0267 ACPI_WDAT_SET_STOPPED_STATE, 0, NULL);
0268 }
0269
0270 static int wdat_wdt_ping(struct watchdog_device *wdd)
0271 {
0272 return wdat_wdt_run_action(to_wdat_wdt(wdd), ACPI_WDAT_RESET, 0, NULL);
0273 }
0274
0275 static int wdat_wdt_set_timeout(struct watchdog_device *wdd,
0276 unsigned int timeout)
0277 {
0278 struct wdat_wdt *wdat = to_wdat_wdt(wdd);
0279 unsigned int periods;
0280 int ret;
0281
0282 periods = timeout * 1000 / wdat->period;
0283 ret = wdat_wdt_run_action(wdat, ACPI_WDAT_SET_COUNTDOWN, periods, NULL);
0284 if (!ret)
0285 wdd->timeout = timeout;
0286 return ret;
0287 }
0288
0289 static unsigned int wdat_wdt_get_timeleft(struct watchdog_device *wdd)
0290 {
0291 struct wdat_wdt *wdat = to_wdat_wdt(wdd);
0292 u32 periods = 0;
0293
0294 wdat_wdt_run_action(wdat, ACPI_WDAT_GET_CURRENT_COUNTDOWN, 0, &periods);
0295 return periods * wdat->period / 1000;
0296 }
0297
0298 static const struct watchdog_info wdat_wdt_info = {
0299 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
0300 .firmware_version = 0,
0301 .identity = "wdat_wdt",
0302 };
0303
0304 static const struct watchdog_ops wdat_wdt_ops = {
0305 .owner = THIS_MODULE,
0306 .start = wdat_wdt_start,
0307 .stop = wdat_wdt_stop,
0308 .ping = wdat_wdt_ping,
0309 .set_timeout = wdat_wdt_set_timeout,
0310 .get_timeleft = wdat_wdt_get_timeleft,
0311 };
0312
0313 static int wdat_wdt_probe(struct platform_device *pdev)
0314 {
0315 struct device *dev = &pdev->dev;
0316 const struct acpi_wdat_entry *entries;
0317 const struct acpi_table_wdat *tbl;
0318 struct wdat_wdt *wdat;
0319 struct resource *res;
0320 void __iomem **regs;
0321 acpi_status status;
0322 int i, ret;
0323
0324 status = acpi_get_table(ACPI_SIG_WDAT, 0,
0325 (struct acpi_table_header **)&tbl);
0326 if (ACPI_FAILURE(status))
0327 return -ENODEV;
0328
0329 wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL);
0330 if (!wdat)
0331 return -ENOMEM;
0332
0333 regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs),
0334 GFP_KERNEL);
0335 if (!regs)
0336 return -ENOMEM;
0337
0338
0339 if (tbl->timer_period < 1)
0340 return -EINVAL;
0341 if (tbl->min_count > tbl->max_count)
0342 return -EINVAL;
0343
0344 wdat->period = tbl->timer_period;
0345 wdat->wdd.min_hw_heartbeat_ms = wdat->period * tbl->min_count;
0346 wdat->wdd.max_hw_heartbeat_ms = wdat->period * tbl->max_count;
0347 wdat->wdd.min_timeout = 1;
0348 wdat->stopped_in_sleep = tbl->flags & ACPI_WDAT_STOPPED;
0349 wdat->wdd.info = &wdat_wdt_info;
0350 wdat->wdd.ops = &wdat_wdt_ops;
0351 wdat->pdev = pdev;
0352
0353
0354 for (i = 0; i < pdev->num_resources; i++) {
0355 void __iomem *reg;
0356
0357 res = &pdev->resource[i];
0358 if (resource_type(res) == IORESOURCE_MEM) {
0359 reg = devm_ioremap_resource(dev, res);
0360 if (IS_ERR(reg))
0361 return PTR_ERR(reg);
0362 } else if (resource_type(res) == IORESOURCE_IO) {
0363 reg = devm_ioport_map(dev, res->start, 1);
0364 if (!reg)
0365 return -ENOMEM;
0366 } else {
0367 dev_err(dev, "Unsupported resource\n");
0368 return -EINVAL;
0369 }
0370
0371 regs[i] = reg;
0372 }
0373
0374 entries = (struct acpi_wdat_entry *)(tbl + 1);
0375 for (i = 0; i < tbl->entries; i++) {
0376 const struct acpi_generic_address *gas;
0377 struct wdat_instruction *instr;
0378 struct list_head *instructions;
0379 unsigned int action;
0380 struct resource r;
0381 int j;
0382
0383 action = entries[i].action;
0384 if (action >= MAX_WDAT_ACTIONS) {
0385 dev_dbg(dev, "Skipping unknown action: %u\n", action);
0386 continue;
0387 }
0388
0389 instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL);
0390 if (!instr)
0391 return -ENOMEM;
0392
0393 INIT_LIST_HEAD(&instr->node);
0394 instr->entry = entries[i];
0395
0396 gas = &entries[i].register_region;
0397
0398 memset(&r, 0, sizeof(r));
0399 r.start = gas->address;
0400 r.end = r.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1;
0401 if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
0402 r.flags = IORESOURCE_MEM;
0403 } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
0404 r.flags = IORESOURCE_IO;
0405 } else {
0406 dev_dbg(dev, "Unsupported address space: %d\n",
0407 gas->space_id);
0408 continue;
0409 }
0410
0411
0412 for (j = 0; j < pdev->num_resources; j++) {
0413 res = &pdev->resource[j];
0414 if (resource_contains(res, &r)) {
0415 instr->reg = regs[j] + r.start - res->start;
0416 break;
0417 }
0418 }
0419
0420 if (!instr->reg) {
0421 dev_err(dev, "I/O resource not found\n");
0422 return -EINVAL;
0423 }
0424
0425 instructions = wdat->instructions[action];
0426 if (!instructions) {
0427 instructions = devm_kzalloc(dev,
0428 sizeof(*instructions),
0429 GFP_KERNEL);
0430 if (!instructions)
0431 return -ENOMEM;
0432
0433 INIT_LIST_HEAD(instructions);
0434 wdat->instructions[action] = instructions;
0435 }
0436
0437 list_add_tail(&instr->node, instructions);
0438 }
0439
0440 wdat_wdt_boot_status(wdat);
0441 wdat_wdt_set_running(wdat);
0442
0443 ret = wdat_wdt_enable_reboot(wdat);
0444 if (ret)
0445 return ret;
0446
0447 platform_set_drvdata(pdev, wdat);
0448
0449
0450
0451
0452
0453
0454 if (watchdog_timeout_invalid(&wdat->wdd, timeout)) {
0455 dev_warn(dev, "Invalid timeout %d given, using %d\n",
0456 timeout, WDAT_DEFAULT_TIMEOUT);
0457 timeout = WDAT_DEFAULT_TIMEOUT;
0458 }
0459
0460 ret = wdat_wdt_set_timeout(&wdat->wdd, timeout);
0461 if (ret)
0462 return ret;
0463
0464 watchdog_set_nowayout(&wdat->wdd, nowayout);
0465 watchdog_stop_on_reboot(&wdat->wdd);
0466 watchdog_stop_on_unregister(&wdat->wdd);
0467 return devm_watchdog_register_device(dev, &wdat->wdd);
0468 }
0469
0470 static int wdat_wdt_suspend_noirq(struct device *dev)
0471 {
0472 struct wdat_wdt *wdat = dev_get_drvdata(dev);
0473 int ret;
0474
0475 if (!watchdog_active(&wdat->wdd))
0476 return 0;
0477
0478
0479
0480
0481
0482
0483
0484 wdat->stopped = false;
0485 if (acpi_target_system_state() == ACPI_STATE_S0 ||
0486 !wdat->stopped_in_sleep) {
0487 ret = wdat_wdt_stop(&wdat->wdd);
0488 if (!ret)
0489 wdat->stopped = true;
0490 } else {
0491 ret = wdat_wdt_ping(&wdat->wdd);
0492 }
0493
0494 return ret;
0495 }
0496
0497 static int wdat_wdt_resume_noirq(struct device *dev)
0498 {
0499 struct wdat_wdt *wdat = dev_get_drvdata(dev);
0500 int ret;
0501
0502 if (!watchdog_active(&wdat->wdd))
0503 return 0;
0504
0505 if (!wdat->stopped) {
0506
0507
0508
0509
0510
0511 ret = wdat_wdt_stop(&wdat->wdd);
0512 if (ret)
0513 return ret;
0514
0515 ret = wdat_wdt_set_timeout(&wdat->wdd, wdat->wdd.timeout);
0516 if (ret)
0517 return ret;
0518
0519 ret = wdat_wdt_enable_reboot(wdat);
0520 if (ret)
0521 return ret;
0522
0523 ret = wdat_wdt_ping(&wdat->wdd);
0524 if (ret)
0525 return ret;
0526 }
0527
0528 return wdat_wdt_start(&wdat->wdd);
0529 }
0530
0531 static const struct dev_pm_ops wdat_wdt_pm_ops = {
0532 NOIRQ_SYSTEM_SLEEP_PM_OPS(wdat_wdt_suspend_noirq, wdat_wdt_resume_noirq)
0533 };
0534
0535 static struct platform_driver wdat_wdt_driver = {
0536 .probe = wdat_wdt_probe,
0537 .driver = {
0538 .name = "wdat_wdt",
0539 .pm = pm_sleep_ptr(&wdat_wdt_pm_ops),
0540 },
0541 };
0542
0543 module_platform_driver(wdat_wdt_driver);
0544
0545 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
0546 MODULE_DESCRIPTION("ACPI Hardware Watchdog (WDAT) driver");
0547 MODULE_LICENSE("GPL v2");
0548 MODULE_ALIAS("platform:wdat_wdt");